Java中的锁框架与线程同步的区别
线程同步机制可以使用 java.util.concurrent
包中的 Lock
框架来实现。锁框架像同步块一样工作,除了锁可以比 Java 的同步块更复杂。锁允许更灵活的同步代码结构。 Java 5 中引入了这种新方法来解决下面提到的同步问题。
下面来看看一个 Vector
类,它有许多同步方法。当一个类中有 100
个同步方法时,在任何给定时间点,这 100 个方法中只能执行一个线程。在任何给定时间点,使用同步块只允许一个线程访问一个方法。这是一个非常昂贵的操作。锁通过允许为不同目的配置各种锁来避免这种情况。一个人可以在一个锁下同步几个方法,在另一个锁下同步其他方法。这允许更多的并发性并提高整体性能。
示例
锁通过 lock()
方法获取并通过 unlock()
方法释放。 在没有 lock()
的情况下调用 unlock()
将引发异常。 如前所述,Lock 接口存在于 java.util.concurrent.locks
包中,而 ReentrantLock
实现了 Lock 接口。
注意:
lock()
调用的次数应始终等于unlock()
调用的次数。
在下面的代码中,用户创建了一个名为 TestResource
的资源,它有两个方法和两个不同的锁。 有两个名为 DisplayJob
和 ReadJob
的作业。 LockTest
类创建 5
个线程来完成 DisplayJob
和 5 个线程来完成 ReadJob
。 所有 10 个线程共享一个资源 TestResource
。
运行结果如下:
在上面的示例中, DisplayJob
不需要等待 ReadJob
线程完成任务,因为 ReadJob 和 Display 作业使用两个不同的锁。 synchronized
无法做到这一点。
区别如下:
参数 | 锁框架 | 同步 |
---|---|---|
跨方法 | 是的,可以跨方法实现锁,可以在方法1中调用 lock() ,在方法2中调用 unlock() 。 |
不可能 |
尝试获取锁 | 是的,锁框架支持 trylock(timeout) 方法,如果资源可用,它将获取资源的锁,否则返回 false ,线程不会被阻塞。 |
同步时不可能 |
公平锁管理 | 是的,在锁框架的情况下可以使用公平锁管理。 它将锁交给长时间等待的线程。 即使在将公平模式设置为 true 的情况下,如果对 trylock 进行了编码,也会首先提供它。 |
同步时不可能 |
等待线程列表 | 是的,使用 Lock 框架可以看到等待线程列表 |
同步时不可能 |
释放异常中的锁定 | Lock.lock(); myMethod();Lock.unlock(); 如果 myMethod() 抛出任何异常,则无法在此代码中执行 unlock() |
在这种情况下,同步工作很清楚,它释放锁 |