多线程之等待唤醒机制

  等待唤醒机制适用于解决生产者消费者问题。生产者消费者问题打一个比方,有一家商店,商店里有各种你想要的东西,也就是资源。商店有一个老板,也就是生产者,你去买东西就是消费者。当你去商店买一样东西的时候,商店里有这样东西你才能买到,如果没有你就需要等有这样东西的时候才能买。而商店老板每次也会等到这样东西卖完了才会去生产这样东西。生产者和消费者都需要对一种资源进行操作,这就相当于是两个线程对一种资源进行了操作,也就涉及到了线程的安全问题。
  针对这种问题,Java提供了一种等待唤醒机制,也就是当有这种资源的时候才能对资源进行获取,否则就要等待。反之,如果没有这种资源的时候才能对资源进行生产,否则就要等待。每一次对资源操作之后都要对线程进行唤醒,否则就会造成线程间的相互等待,造成死锁现象。

线程执行流程图:
多线程之等待唤醒机制_第1张图片

package test;

public class Demo {
    public static void main(String[] args) {
        Student s = new Student();

        SetStudent st = new SetStudent(s);
        GetStudent gt = new GetStudent(s);

        Thread t1 = new Thread(st);
        Thread t2 = new Thread(gt);

        t1.start();//启动线程t1
        t2.start();//启动线程t2

    }
}

定义学生类:

package test;

public class Student {
    String name;
    int age;
    boolean flag;


    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", flag=" + flag + "]";
    }


}

产生数据:

package test;

public class SetStudent implements Runnable{

    private Student s;
    int x = 0;

    public SetStudent(Student s) {
        this.s = s;
    }

    public void run() {
        while(true) {
            synchronized (s) {
                if(s.flag) {
                    try {
                        s.wait();//使线程t2等待,如果锁被释放后是从这里醒过来的
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

                if(x%2 == 0) {
                    s.name = "小叮当";
                    s.age = 11;
                }else {
                    s.name = "猪猪侠";
                    s.age = 18;
                }
                s.flag = true;
                s.notify();//唤醒线程,唤醒后并不是立即释放,而是先抢夺资源,当抢到CPU的使用权时,才继续执行
                x++;
            }
        }
    }
}

获取数据:

package test;

public class GetStudent implements Runnable{

    private Student s;

    public GetStudent(Student s) {
        this.s = s;
    }

    @Override
    public void run() {

        synchronized(s) {
            while(true) {
                if(!s.flag) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.err.println(s);
                s.flag = false;
                s.notify();

            }
        }
    }



}

你可能感兴趣的:(Java)