Java 线程三
在前一章的练习中,我们使用了 while 来实现每个线程被唤醒时都判断标记,以及使用 notyfyAll() 方法来唤醒所有线程,但这样做会发现,不应该被唤醒的线程也将被唤醒,这样做并不是最好的做法,下面介绍JDK1.5以后的新功能。
使用Lock和Condition 接口
Lock 接口通过 创建ReentrantLock 类来获取对象
Condition 接口通过 Lock的newCondition方法来获取对象
Lock 接口的 lock() 方法用来获取锁, 类似 synchronized
Lock 接口的 unLock() 方法释放锁, 必须要做的动作,建议放在 finally 块中
Condition 接口的await() 方法,用来设置当前线程等待
Condition 接口的signal()方法,用来唤醒其它线程
解决不应该被唤醒的线程也被唤醒的主要动作,是创建两个Condition对象,谁等待,谁唤醒则调用相应的方法,关键代码如下:
<span style="white-space:pre"> </span>private Condition con_pro = lock.newCondition(); //生产者线程
private Condition con_cus = lock.newCondition(); //消费者线程
当消费者消费完成后执行 con_cus.await(); 让消费方线程等待,并唤醒生产方线程 con_pro.signal();
完整代码如下:
import java.util.concurrent.locks.*;
class Resource //资源类
{
private String name;
private int count;
public boolean flag;
private Lock lock = new ReentrantLock();
private Condition con_pro = lock.newCondition(); //生产者线程
private Condition con_cus = lock.newCondition(); //消费者线程
public synchronized void set(String name) {
lock.lock();
try{
while(flag) { //每次唤醒时都会进行判断标记
try {
con_pro.await(); //让生产方线程等等
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
this.name = name+"..."+count++;
System.out.println(Thread.currentThread().getName()+ "生产者:" + this.name);
flag = true;
con_cus.signal(); //唤醒消费方线程
}finally{
lock.unlock();
}
}
public void out(){
lock.lock();
try{
while(!flag) { //每次唤醒时都会进行判断标记
try {
con_cus.await(); //消费方线程等待
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+".....消费者:" + this.name );
flag = false;
con_pro.signal();//唤醒生产方线程
}finally{
lock.unlock();
}
}
}
class Producer implements Runnable{
private Resource res;
public Producer(Resource res) {
this.res = res;
}
@Override
public void run() {
while(true){
res.set("张三");
}
}
}
class Consumer implements Runnable{
private Resource res;
public Consumer(Resource res) {
this.res = res;
}
@Override
public void run() {
while(true){
res.out();
}
}
}
public class Demo3 {
public static void main(String[] args) {
Resource res = new Resource();
Producer pro = new Producer(res);
Consumer con = new Consumer(res);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}