Java第二十五天,多线程之等待唤醒机制

当线程被创建并且被启动之后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,而是具有以下多种状态:

这六种状态之间的转换关系如下:

1.等待唤醒机制

注意:

(1)两个线程之间必须用同步代码块给包裹起来,保证等待和唤醒线程同一时间段只能有一个执行,用以保证共享数据安全。

(2)同步使用的锁对象必须是同一个对象。

(3)必须使用锁对象的wait()和notify()方法完成等待唤醒的操作。

(4)要注意多个被synchronized修饰的代码块是只允许在同一时刻运行一个;也就是说如果要和循环(特别是死循环)配合使用的话,要注意二者之间的包含关系。

代码:

package com.lanyue.day25;

public class Consumer extends Thread{

    Resource r = null;

    public void setLock(Resource r){

        this.r = r;
    }

    @Override
    public void run() {

        while(true){

            synchronized (r){

                try {
                    r.wait();
                } catch (InterruptedException e) {
                    System.out.println("系统发生奔溃");
                }

                try {

                    System.out.println("消费中======>");
                    Thread.sleep(1000);
                    r.num--;
                    r.isEmpty = true;
                    System.out.println("当前货物剩余量:" + r.num);
                    Thread.sleep(1000);

                } catch (InterruptedException e) {

                    System.out.println("系统奔溃");
                }

            }
        }
    }
}
package com.lanyue.day25;

public class Producer extends Thread{

    Resource r = null;

    public void setLock(Resource r){

        this.r = r;
    }

    @Override
    public void run() {

        while(true){

            synchronized (r){

                if(r.isEmpty){

                    try {

                        System.out.println("生产中======>");
                        Thread.sleep(1000);
                        r.num++;
                        r.isEmpty = false;
                        System.out.println("当前货物剩余量:" + r.num);
                        Thread.sleep(1000);

                    } catch (InterruptedException e) {

                        System.out.println("系统奔溃");
                    }


                }else{

                    r.notify();
                }
            }
        }
    }
}
package com.lanyue.day25;

public class Resource {

    public boolean isEmpty = true;
    public Integer num = 0;
}
package com.lanyue.day25;

public class TestDemo {

    public static void main(String[] args) {

        Resource r = new Resource();

        Producer in = new Producer();
        Consumer out = new Consumer();

        in.setLock(r);
        out.setLock(r);

        in.start();
        out.start();
    }
}

很多人会纳闷为什么是

while(true){

      synchronized(obj){

      }

}

而不是

synchronized(obj){

      whle(true){
      }
}

因为如果是后者,将会导致同一时刻只能执行一个死循环,言外之意也就是说会导致另一个死循环停止执行,不再是所谓的死循环。两个线程也仅仅只会留下一个。

原文地址:https://www.cnblogs.com/viplanyue/p/12700524.html