多线程之间的通信-生产者消费者-中断一个线程

上一节 - 多线程安全

一. 多线程之间如何实现通讯

1.1 什么是多线程之间的通讯

多线程之间通信,其实就是多个线程在操作同一个资源,但是操作的动作不同。

1.2 多线程之间通讯需求

需求:第一个线程写入(input)用户,另一个线程读取(out)用户,实现读一个,写一个操作。
生产者消费者

**涉及到 wait 、 notify **
共享资源源实体类:

class Person{
    protected String name;
    protected String sex;
    protected boolean flag = false;
}

生产线 线程资源

class Product extends Thread{
    private Person person;

    public Product(Person person){
        this.person = person;
    }

    @Override
    public void run() {
        int count = 0;
        while(true){
            synchronized(person) {
                // 当 flag 为 flase 时,生产者生产产品,消费者消费产品
                // 当 flag 为 true 时,生产者停止生产产品,消费者开始消费产品
                if(person.flag){
                    try {
                        // wait 的作用是让线程从运行状态变为 休眠状态,类比 sleep
                        // 但两者还是有差异:wait() 可以释放锁,sleep 不能释放
                        // wait 和 synchronized 一起在多线程之间实现同步
                        person.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (count == 0) {
                    person.name = "王盼";
                    person.sex = "女";
                } else {
                    person.name = "王盼盼";
                    person.sex = "男";
                }
                count = (count + 1) % 2;
                person.flag = true;
                // 和 wait() 一起使用,用来唤醒一个线程,将线程聪慧阻塞状态变为与运行状态
                person.notify();
            }
        }
    }
}

消费者线程资源

class Custom extends Thread{
    private Person person;

    public Custom(Person person){
        this.person = person;
    }

    @Override
    public void run() {
        while(true){
            synchronized(person) {
                if(!person.flag == true){
                    try {
                        person.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(person.name + "----" + person.sex);
                person.flag = false;
                person.notify();
            }
        }
    }
}

二. 中断一个线程

老板让李四去银行给一个陌生用户转账,李但老板突然来电话了,说转账的对方是个骗子,需要赶紧停止转账,那张三该如何通知李四停止呢?

  • 通过共享的标记来进行沟通

实例1

package sin_2020_02_22.sin_2020_02_23;

public class StopThread {

    private static class ThreadDemo extends Thread{
        private volatile boolean quit = false;

        ThreadDemo(){
            super("李四");
        }

        public void setQuit(boolean quit) {
            this.quit = quit;
        }

        @Override
        public void run() {
            while(!quit){
                System.out.println(this.getName()+" 我正在转账不要烦我");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(this.getName()+" 对面是骗子我不转了");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new ThreadDemo();
        System.out.println("开始转吧");
        thread.start();
        Thread.sleep(1000 * 10);
        System.out.println("对方是骗子,可别转了");
        ((ThreadDemo) thread).setQuit(true);
        System.out.println("给说了");
        thread.join();
        System.out.println("李四停止转账");
    }
}


  • 调用 interrupt() 方法来通知(与 interruputed() 配合使用)

实例2

package sin_2020_02_22.sin_2020_02_23;

public class StopThread1 {
    private static class ThreadDemo extends Thread{
        ThreadDemo(){
            super("李四");
        }

        @Override
        public void run() {
            while(!this.isInterrupted()){
                System.out.println(this.getName()+" 我正在转账不要烦我");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    //e.printStackTrace();
                    System.out.println("我从睡梦中惊醒");
                    break;
                }
            }
            System.out.println(this.getName()+" 对面是骗子我不转了");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new ThreadDemo();
        System.out.println("开始转吧");
        thread.start();
        Thread.sleep(5000);
        System.out.println("对方是骗子,可别转了");
        thread.interrupt();
        System.out.println("给说了");
        thread.join();
        System.out.println("李四停止转账");
    }
}

实例1 实例2
thread.interrupt() thread.setQuit()
interrupted() quit
this.isInputerrupted() quit判断
发布了98 篇原创文章 · 获赞 5 · 访问量 6450

猜你喜欢

转载自blog.csdn.net/weixin_43580746/article/details/104444637