您的位置:首页 > 编程语言 > Java开发

Java多线程学习(九)

2016-03-09 19:01 543 查看
在JDK1.5中新增加了ReentrantLock类页能够实现同步的效果,而且在扩张功能上也更加强大,使用上也更加方便。

ReentrantLock
首先先看一下ReentrantLock的方法:





然后来看一个ReentrantLock的使用实例。
public class Service extends Thread {
private Lock lock = new ReentrantLock();
public void run(){
lock.lock();
for(int i = 0; i < 5; i++){
System.out.println(Thread,currentThread().getName());
}
lock.unLock();
}

public static void main(String [] args){
Service s1 = new Service();
Service s2 = new Service();
Service s3 = new Service();
s1.start();
s2.start();
s3.start();
}

运行结果:每个线程是同步的,但哪个线程先执行是不一定的。
调用ReentrantLock对象的lock()方法获取锁,调用unlock()方法释放锁。unLock()方法也可放到finally代码块中。

Condition
首先先看一下Condition类的方法:


Condition对象相当于“对象监视器”实例,线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。而synchronized就相当于整个Lock对象中就只有一个单一的Condition,所有线程都注册到一个Condition中,线程开始notifyAll时,需要通知所有的WAITING线程。
public class MyThread extends Thread {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void run(){
lock.lock();
condition.await();
lock.unLock();
}
public static void main(String [] args){
MyThread t = new MyThread();
t.start();
}
}
在调用Condition的await方法之前,必须要先获得锁,即必须先调用Lock的lock方法,否则会抛出异常。

用Condition实现等待/通知模式
Condition中的await()方法相当于wait()方法,signal()/signalAll()方法相当于notify()/notifyAll()方法。
使用多个Condition实现通知部分线程
既要先对线程组进行分类,然后在唤醒指定组中的线程
public class MyService {
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
public void awaitA(){
lock.lock();
conditionA.await();
lock.unLock();
}
public void awaitB(){
lock.lock();
conditionB.await();
lock.unLock();
}
public void signalA(){
lock.lock();
conditionA.signalAll();
lock.unLock();
}
public void signalB(){
lock.lock();
conditionB.signalAll();
lock.unLock();
}
}
调用conditionB的signalAll方法只有ConditionB的waiting线程被唤醒,而不会唤醒conditionAl的waiting线程。

公平锁与非公平锁
公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即按照先进先出的顺序。打印结果基本有序。
非公平锁就是一种获取锁的抢占机制,是随机获得锁的,某些线程可能一直都拿不到锁。打印结果基本乱序。默认的
Lock lock = new ReentrantLock(true); //公平锁
Lock lock = new ReentrantLock(false); //非公平锁

使用ReentrantReadWriteLock类
ReentrantLock类具有完全互斥排他的效果,即同一个时间内只有一个线程在执行lock方法后面的任务。这样的效率极低。所以JDK中提供了一种ReentrantReadWriteLock类,在某些不需要操作实例变量的方法中,可以提高代码执行速度。
读写锁有两个锁,一个是读操作相关的锁,称为共享锁;另一个是写操作相关的锁,称为排它锁。多个读锁之间不互斥,读锁和写锁互斥,写锁和写锁互斥。在没有线程进行写入操作时,进行读操作的多个线程都可以获取锁,而进行写操作的线程只有在获取写锁之后才能进行写入操作。即多个线程可以同时进行读取操作,但是同一个时刻只允许一个线程进行写操作。
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
lock.readLock().lock();
lock.writeLock().lock();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: