线程的通信

线程通信

线程的通信就是一个数据可以让两个线程轮流打印 你打印一下 我打印一下 

线程的通信需要用到 wait() notify() 和 notifyAll()方法来使线程进行通信

 

通信方法:

wait() : 一旦执行此方法 当前线程就进入阻塞状态,并释放同步监视器(锁)

notify(): 一旦执行此方法,就会被唤醒的wait线程,如果有多个线程被wait就会唤醒优先级高的

notifuAll(): 一旦执行此方法释放所有被wait()方法阻塞的线程

说明:

说明:
   1: wait() notify() notifyAll() 必须使用在同步代码块或者同步范方法中
   2: 这三个方法必须都是同一个同步监视器调用

 

 

eg:

class ThreadTon implements  Runnable{
    private  int num = 1;
    @Override
    public void run() {
        while (true){
            synchronized(this){
                notify(); // 让上一个阻塞的线程放开
                if(num < 100){
                    try {

                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+" : "+num);
                    num ++;


                    try {
                        ///调用方法是进来的线程进入阻塞状态, 执行wait会释放锁 一个线程执行了wait另一个就拿到了执行了
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    break;
                }
            }

        }
    }
}

 

 

 

 

面试题:

 面试题: sleep() 和wait()异同

 

  

   相同:一旦执行都会使线程进入阻塞状态

   不同点:
            1: 两个方法的声明位置不同 Thread中声明sleep() Object中声明wait()
            2: 调用的范围: sleep随时可以用, wait()必须使用在同步代码或者同步方法中
            3: 是否释放同步监视器: 如果两个方法都是用在同步代码块和同步方法中 sleep()不会释放锁,wait()会释放锁
sleep和wait异同点

 

 

线程通信的经典例题: 生产者消费者

生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处 取走产品,
店员一次只能持有固定数量的产品(比如:20),
如果生产者试图 生产更多的产品,店员会叫生产者停一下,
如果店中有空位放产品了再通 知生产者继续生产;如果店中没有产品了,
店员会告诉消费者等一下,如 果店中有产品了再通知消费者来取走产品。

 

首先我们要分析具体的信息

分析:
  1; 是否有多线程问题? 是,生产者线程, 消费者线程
  2: 是否有共享数据? 店员(或者产品)
  3: 如何解决线程的安全问题? 同步机制三中方法
  4: 是否涉及线程的通信

 

 

public class ProductTestOne {
    public static void main(String[] args) {
        ClerkOne clerkOne = new ClerkOne();
        Consum c1 = new Consum(clerkOne);

        Produc p1 = new Produc(clerkOne);
        p1.start();
        c1.start();

    }
}



class ClerkOne{  // 商品


    private  int count = 0; // 记录商品的数量


    public synchronized  void consumPro() {  // 消费方法

        if(count > 0){
            notify();  // 释放对方的线程
            System.out.println(Thread.currentThread().getName() + " 开始消费第几个 : "+count);
            count --;
        }else{ // 等待
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void producPro() {  // 生产

        if(count < 20){
            count ++;
            System.out.println(Thread.currentThread().getName() +"  开始生产第: "+count);
            notify();
        }else{ // 等待
            try {
                wait();  // 线程通信
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consum extends Thread{  // 消费者
    private  ClerkOne clerkOne;

    
    public Consum(ClerkOne clerkOne){
        this.clerkOne = clerkOne;
    }

    @Override
    public void run() {
        System.out.println("消费者开始消费");
        while (true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerkOne.consumPro();
        }
    }
}

class Produc extends  Thread{  // 生产者
    private  ClerkOne clerkOne;
    
    public Produc (ClerkOne clerkOne){
        this.clerkOne = clerkOne;
    }

    @Override
    public void run() {
        System.out.println("生产者开始生产");
        while (true){  // sleep下 给生产消费留下余地
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerkOne.producPro();
        }
    }
}
生产者消费者解答

 

 

 

 

.

posted @ 2019-11-18 14:26  可爱的红领巾  阅读(137)  评论(0编辑  收藏  举报