黑马程序员——线程中等待唤醒机制及jdk5版本lock的深入思考

来源:互联网 发布:抑郁和悲伤的区别 知乎 编辑:程序博客网 时间:2024/05/20 13:16

------- android培训、java培训、期待与您交流! ----------

     通过前几天的学习,对唤醒机制中的wait()方法一直有点困惑。先看两段段简单的代码片段:

synchronized(s){if(!s.flag)try{s.wait();}catch (Exception e){}if(x==0){s.name="张三";s.sex="男";x=1;}else{s.name="李思";s.sex="女";x=0;}s.flag=false;s.notify();}


下一段:

synchronized(s){if(s.flag)try{s.wait();}catch (Exception e){}System.out.println("姓名:"+s.name+"……性别:"+s.sex);s.flag=true;s.notify();}


    疑惑是:当第一段代码执行到wait()时,线程休眠,那么他在锁里面,锁没有释放,第二段代码也执行不了。后来查了wail()的用法,才恍然大悟。原来Object类中wait()方法是这样的:
    final void wait() throws InterruptedException通知当前的线程进入睡眠状态直到其他线程进入调用notify()唤醒他。在睡眠之前释放掉所占有的“锁标志”,则其占用的所有synchronized代码块可被别的线程使用。但还是有一点疑惑,就是判断是是否wait的if语句写在synchronized外面则会出错,介系为什么呢?

        关于同步代码块的使用,jdk1.5及以后版本做了很好的改进,那就是使用lock()。有个生产消费的例子,先使用synchronized,代码如下所示:

class ProductDemo {public static void main(String[] args) {Src s = new Src();Produce pro = new Produce(s);consume con = new consume(s);Thread t1 = new Thread(pro);Thread t2 = new Thread(con);Thread t3 = new Thread(pro);Thread t4 = new Thread(con);t1.start();t2.start();t3.start();t4.start();}}class Src {private String name;private int index = 0;public boolean flag = false;public void set(String name) {this.name = name;System.out.println(name + "-----" + (++index) + "----被生产");}public void get() {System.out.println(name + "-----" + index + "----------被消费");}}class Produce implements Runnable {private Src s;Produce(Src s) {this.s = s;}public void run() {while (true) {synchronized (s) {while (s.flag)try {s.wait();} catch (Exception e) {}s.set("商品");s.flag = true;s.notifyAll();}}}}class consume implements Runnable {private Src s;consume(Src s) {this.s = s;}public void run() {while (true) {synchronized (s) {while (!s.flag)try {s.wait();} catch (Exception e) {}s.get();s.flag = false;s.notifyAll();}}}}


用lock来写如下:

import java.util.concurrent.locks.*;class ProductLockDemo {public static void main(String[] args) {Src s = new Src();Produce pro = new Produce(s);consume con = new consume(s);Thread t1 = new Thread(pro);Thread t2 = new Thread(con);Thread t3 = new Thread(pro);Thread t4 = new Thread(con);t1.start();t2.start();t3.start();t4.start();}}class Src {private String name;private int index = 0;public boolean flag = false;Lock lock = new ReentrantLock();Condition condition_pro = lock.newCondition();Condition condition_con = lock.newCondition();public void set(String name) {this.name = name;System.out.println(name + "-----" + (++index) + "----被生产");}public void get() {System.out.println(name + "-----" + index + "----------被消费");}}class Produce implements Runnable {private Src s;Produce(Src s) {this.s = s;}public void run() {while (true) {s.lock.lock();try {while (s.flag) {s.condition_pro.await();}s.set("商品");s.flag = true;s.condition_con.signal();} catch (Exception e) {} finally {s.lock.unlock();}}}}class consume implements Runnable {private Src s;consume(Src s) {this.s = s;}public void run() {while (true) {s.lock.lock();try {while (!s.flag)try {s.condition_con.await();} catch (Exception e) {}s.get();s.flag = false;s.condition_pro.signal();} finally {s.lock.unlock();}}}}


原创粉丝点击