并发编程-notify和wait

2020-01-30  本文已影响0人  zhaoyang66

通过wait和notify来实现发布订阅。就是线程1(生产者)生产一个数字,线程2(消费者)消费一个数字。消费的速度决定于生产者的速度。
主对象 Mymain.java

package tv.lab.thread;

public class Mymain {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        //创建2个任务,分别是r01和r02,并分别用2个线程运行这2个任务。注意,这里是2个线程,每个线程上有一个独立的任务。线程共享的对象是ticket
        Runnable01 r01 = new Runnable01(ticket);  
        Runnable02 r02 = new Runnable02(ticket);
        Thread t1 = new Thread(r01, "t1");  //声明线程t1
        Thread t2 = new Thread(r02, "t2");  //声明线程t2

        t1.start();
        t2.start();
    }
}

共享对象Ticket.java

package tv.lab.thread;

public class Ticket {
    int num = 0;
    boolean hasTicket = false;
}

生产对象Runnable01.java,这个是要生产数字的,产出的数字供消费者任务Runnable02.java消费

package tv.lab.thread;

import java.util.concurrent.TimeUnit;

public class Runnable01 implements Runnable {

    Ticket ticket;

    public Runnable01(Ticket ticket) {
        this.ticket = ticket;  //将共享对象通过构造函数传递过来
    }

    @Override
    public void run() {
        while (true) {
            try {
                TimeUnit.MILLISECONDS.sleep(10);  //休眠10毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (Ticket.class) { 
                if (ticket.hasTicket == true) {
                    try {
                        Ticket.class.wait();  //如果为true,就是有票情况下,就等待,直到票被消费掉后,再产生新的票,如果不被消费,就一直挂起。
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println(Thread.currentThread().getName() + " " + ++ticket.num);
                    ticket.hasTicket = true;
                    Ticket.class.notify();  //将等待的线程激活
                }
            }
        }
    }
}

对上面代码的说明

消费任务Runnable02.java,当生产者生产后,这个任务用来消费任务

package tv.lab.thread;

public class Runnable02 implements Runnable {

    Ticket ticket;

    public Runnable02(Ticket ticket) {
        this.ticket = ticket;
    }

    @Override
    public void run() {
        while (true) {

            synchronized (Ticket.class) {
                if (ticket.hasTicket == false) {
                    try {
                        Ticket.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {  //如果有票,就打印出来
                    System.out.println("   " + Thread.currentThread().getName() + " " + ticket.num);
                    ticket.hasTicket = false;
                    Ticket.class.notify();
                }
            }
        }
    }
}

执行结果如下:
生产和消费成对出现。当生产一个数字后,就等待(wait)消费任务来消费,并通知消费任务来消费。当消费任务消费后,就挂起,通知生产任务生产。


1580369096121.jpg
上一篇 下一篇

猜你喜欢

热点阅读