Java+Threads+多线程参考手册(2)

和使用synchronized关键字和lock()方法总是把未能获得锁的线程阻塞不同,Lock接口还提供了非阻塞的tryLock()方法。调用tryLock方法的线程如果未能获得锁会立刻返回false,线程可以继续执行其他代码而避免等待,这为程序员提供了更多自由。

Lock接口还提供了一个newCondition () 方法,它返回一个Condition对象。Condition对象的作用和Object用于线程通知的wait-notify机制相同。

1.4       信号量Semaphore
                有时候我们有多个相同的共享资源可以同时被多个线程使用。我们希望在锁的基础上加上一个计数器,根据资源的个数来初始化这个计数器,每次成功的lock操作都会使计数器的值减去1,只要计数器的值不为零就表示还有资源可以使用,lock操作就能成功。每次unlock操作都会给这个计数器加1。只有当计数器的值为0的时候lock操作才会阻塞当前线程。这就是Java中的信号量Semaphore。

Semaphore类提供的方法和Lock接口非常类似,当把信号量的资源个数设置成1时,信号量就退化为普通的锁。

1.5       读写锁ReadWriteLock
                对共享资源的访问通常可以分为读取和写入。在有些应用场景中读取可能需要花费较长时间,我们需要使用互斥锁来阻止并发的写入操作以保证数据的一致性。但是对于并发的读取线程其实并不需要使用同步。事实上只有使数据发生变化的操作才需要同步,我们希望有一种方法可以把读取和写入区分开来,读取和写入的操作之间是互斥的,但是多个读取操作可以同时进行,这样可以有效提高读取密集型程序的性能。J2SE5.0提供了ReadWriteLock接口并提供了实现该接口的ReentrantReadWriteLock类:

public interface ReadWriteLock {

Lock readLock();

Lock writeLock();

}

从接口方法中不难看出读写锁中包含读锁和写锁。实现类ReentrantReadWriteLock为我们提供了更多便捷的方法来使用读写锁,例如isWriteLocked可以用来检测是否被写锁定。

2         线程通知
                除了同步锁,Java Object还有两个可用于线程间通知的同步方法wait和notify。调用对象wait方法的线程会被阻塞在该对象的等待队列中直到其他线程调用notify方法来唤醒它。每次notify调用只能唤醒一个在等待队列中的线程,notifyAll方法可以唤醒所有在该对象等待队列中的线程。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwygwx.html