Java多线程(4)——多线程JDK5.0升级版(传智播客毕老师视频讲解)
来源:互联网 发布:芝加哥艺术学院 知乎 编辑:程序博客网 时间:2024/05/18 00:18
在Java的JDK1.5版本(即5.0版本)以后,api在java,util.concurrent.locks包中提供了Lock接口与Condition接口。
例子
拿上一篇生产者消费者的例子来说:
构建生产者—消费者
1.1、synchronized变为了ReentrantLock对象的lock()方法;
1.2、wait()、notify()、notifyAll()变为了Condition对象的await()、signal()、signalAll();
代码如下:
import java.util.concurrent.locks.*;public class Jdk5Test {private int num;private int value;private boolean flag=true;private ReentrantLock lock=new ReentrantLock();private Condition pro=lock.newCondition();private Condition con=lock.newCondition();public void setMessage(int num,int value){lock.lock(); //上锁try{Thread.sleep(100);}catch(Exception e){}while(!flag) //如过flag为假,表示当前已生产,则生产线程await()try{pro.await();}catch(Exception e){} //由于await()有异常声明,所以应catch或者throwsthis.num=num; //生产this.value=value;System.out.println(Thread.currentThread().getName()+"......."+"生产"+".."+this.num);flag=false; //生产完毕后,将flag置为假con.signal(); //唤醒消费线程lock.unlock(); //解锁}public void getMessage(){lock.lock(); //上锁try{Thread.sleep(100);}catch(Exception e){}while(flag) //如过flag为真,表示当前已消费,则消费线程await()try{con.await();}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"......."+"消费"+"......."+this.num);flag=true; //消费完毕后,将flag置为真pro.signal(); //唤醒生产线程lock.unlock(); //解锁}}public class Producer implements Runnable{private Jdk5Test r;int num=0;int value=5;public Producer(Jdk5Test r){this.r=r;}public void run(){while(true){r.setMessage(num++,value);}}}public class Consumer implements Runnable{private Jdk5Test r;public Consumer(Jdk5Test r){this.r=r;}public void run(){while(true){r.getMessage();}}}public class Wakeup {public static void main(String arg[]){Jdk5Test r=new Jdk5Test();Producer r1=new Producer(r);//线程1Producer r2=new Producer(r);Consumer r3=new Consumer(r);//线程2Consumer r4=new Consumer(r);Thread t1=new Thread(r1);Thread t2=new Thread(r2);Thread t3=new Thread(r3);Thread t4=new Thread(r4);t1.start();t2.start();t3.start();t4.start();}}运行结果如下:
可见,与之前的synchronized、wait、notify没多大区别,但是lock()与unlock()方法使上锁与解锁明朗化,能很容易理解,同时可以声明两个condition类对象,使得在不用全部唤醒而只需唤醒对方即可,效率提高!
但是其本质与synchronized等方法没什么不同;
值得注意的是:
await()方法在调用后没有解锁的功能,因此如果awati()真的报出异常,则程序会执行异常处理,而由于其没有释放掉锁,因此别的线程进不来,导致程序出现死锁的可能;而释放锁相当于释放资源,其为异常发生后必须执行的动作,因此用finally中写如unlock方法;修改代码如下:
import java.util.concurrent.locks.*;public class Jdk5Test {private int num=0;private int value;private boolean flag=true;private ReentrantLock lock=new ReentrantLock();private Condition pro=lock.newCondition();private Condition con=lock.newCondition();public void setMessage() throws InterruptedException{lock.lock(); //上锁try{Thread.sleep(100);}catch(Exception e){}try{while(!flag) //如过flag为假,表示当前已生产,则生产线程await()pro.await(); //由于await()有异常声明,所以应catch或者throwsnum++; //生产System.out.println(Thread.currentThread().getName()+"......."+"生产"+".."+this.num);flag=false; //生产完毕后,将flag置为假con.signal(); //唤醒消费线程}finally{lock.unlock(); //解锁(必须执行的动作)}}public void getMessage() throws InterruptedException{lock.lock(); //上锁try{Thread.sleep(100);}catch(Exception e){}try{while(flag) //如过flag为真,表示当前已消费,则消费线程await()con.await();System.out.println(Thread.currentThread().getName()+"......."+"消费"+"......."+this.num);flag=true; //消费完毕后,将flag置为真pro.signal(); //唤醒生产线程}finally{lock.unlock(); //解锁(必须执行的动作)}}}此异常抛出后,调用其方法的函数内应进行处理,即捕获或者继续抛出,但由于调用其方法的函数为run方法,而run方法其是实现接口Runnable的,在Runnable中没有对run方法进行异常声明,所以其实现子类不允许再往外抛出异常,即应进行内部处理,所以生产线程和消费线程代码修改如下:
public class Producer implements Runnable{private Jdk5Test r;public Producer(Jdk5Test r){this.r=r;}public void run(){while(true){try{r.setMessage();}catch(InterruptedException e){}}}}public class Consumer implements Runnable{private Jdk5Test r;public Consumer(Jdk5Test r){this.r=r;}public void run(){while(true){try{r.getMessage();}catch(InterruptedException e){}}}}
0 0
- Java多线程(4)——多线程JDK5.0升级版(传智播客毕老师视频讲解)
- Java多线程(1)——多线程创建(传智播客毕老师视频讲解)
- Java多线程(2)——多线程安全(传智播客毕老师视频讲解)
- Java多线程(3)——多线程通信(传智播客毕老师视频讲解)
- Java多线程(5)——多线程停止(传智播客毕老师视频讲解)
- Java多线程(6)——Thread类中的一些方法(传智播客毕老师视频讲解)
- Java基础学习__多线程(线程间通信--生产者消费者JDK5.0升级版)
- 【java多线程】【生产者与消费者】【JDK5.0升级版】
- Java中泛型(4)——泛型接口(传智播客毕老师视频讲解)
- Java中IO流(4)——字节流(传智播客毕老师视频讲解)
- jdk5.0多线程学习笔记(一)
- Java中Collection子接口(1)——List接口(传智播客毕老师视频讲解)
- Java中Collection子接口(2)——Set接口(传智播客毕老师视频讲解)
- Java中泛型(1)——泛型介绍(传智播客毕老师视频讲解)
- Java中泛型(2)——泛型类(传智播客毕老师视频讲解)
- Java中泛型(3)——泛型方法(传智播客毕老师视频讲解)
- Java中泛型(5)——泛型限定(传智播客毕老师视频讲解)
- Java中IO流(1)——IO流概述(传智播客毕老师视频讲解)
- 【DP】 HDOJ 3076 ssworld VS DDD
- Linux的input输入子系统:设备驱动之按键驱动
- 快速排序--Java实现代码
- Spring的aop顺序
- GPS定位冷启动和热启动的区别
- Java多线程(4)——多线程JDK5.0升级版(传智播客毕老师视频讲解)
- Cassandra中的数据一致性
- 【恒天云技术分享系列10】OpenStack块存储技术
- yum error
- HDU - 3746 Cyclic Nacklace (KMP求循环节)
- Openstack swift安装部署
- 面试题21 包含min函数的栈
- 黑马程序员--【学习日记七】——集合框架(二)
- Java生成Txt文件及下载