Java教程

Java多线程06:线程通信

本文主要是介绍Java多线程06:线程通信,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Synchronized实现了同步,但不能用实现不同线程之间的消息传递

  • wait()方法表示线程一直等待,直到其他线程通知,与sleep()不同,wait()会释放锁

  • notify()方法唤醒一个处于等待的线程

  • notifyAll()方法唤醒同一个对象上所有调用wait()方法的线程,优先级高的线程优先调度

  • 只能在Synchronized同步方法和同步块中使用,否则抛出异常

管程法

import java.util.ArrayList;

public class Hello {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList();
        Consumer consumer = new Consumer(arrayList);
        Producer producer = new Producer(arrayList);

        //生产消费各十次(注意不能在run()方法里循环十次,不然会生产完所有苹果再消费)
        for (int i = 0; i < 10; i++) {
            new Thread(consumer).start();
            new Thread(producer).start();
        }
    }
}

//定义消费者类
class Consumer implements Runnable{
    //定义列表集合放置苹果
    ArrayList<Integer> arrayList;

    public Consumer(ArrayList arrayList){
        this.arrayList = arrayList;
    }

    @Override
    public void run() {
        //wait()和notify()方法只能在同步块和同步方法中使用
        synchronized (arrayList) {
            if (arrayList.size() == 0) {
                System.out.println("苹果没有了,需要生产");
                try {
                    //wait()方法让线程进入等待,释放锁给生产线程
                    //没有苹果时消费者进入等待,收到唤醒后才会继续执行后续的代码
                    arrayList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
			
            //为了避免生产完立即被消费,设置一个延时
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (arrayList.size() != 0){
                arrayList.remove(0);
                System.out.println("消费了一个苹果,还剩" + arrayList.size() + "个");
            }
            //notify()方法唤醒生产线程
            arrayList.notify();
        }
    }
}

//定义生产者类
class Producer implements Runnable{
    ArrayList<Integer> arrayList;
    //定义盘子满的数量
    int max = 10;

    public Producer(ArrayList arrayList){
        this.arrayList = arrayList;
    }

    @Override
    public void run() {
        synchronized (arrayList) {
            if (arrayList.size() == max) {
                System.out.println("盘子满了,需要消费");
                try {
                    arrayList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            arrayList.add(1);
            System.out.println("生产了一个苹果,还剩" + arrayList.size() + "个");
            arrayList.notify();
        }
    }
}

信号灯法

import java.util.ArrayList;

public class Hello {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList();
        //定义一个标志,为了保证其他线程指向的是同一个标志,需要使用包装类创建引用对象
        Boolean flag = new Boolean(true);
        Consumer consumer = new Consumer(arrayList, flag);
        Producer producer = new Producer(arrayList, flag);
        for (int i = 0; i < 10; i++) {
            new Thread(consumer).start();
            new Thread(producer).start();
        }
    }
}

//定义消费者类
class Consumer implements Runnable{
    ArrayList<Integer> arrayList;
    Boolean flag = new Boolean(true);

    public Consumer(ArrayList arrayList, boolean flag){
        this.arrayList = arrayList;
        this.flag = flag;
    }

    @Override
    public void run() {
        synchronized (arrayList) {
            if (flag) {
                try {
                    arrayList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //当列表长度不为0时,可以消费苹果
            if (arrayList.size() != 0){
                arrayList.remove(0);
                System.out.println("消费了一个苹果,还剩" + arrayList.size() + "个");
            }
			
            //反转标志位,让生产者线程运行
            flag = false;
            arrayList.notify();
        }
    }
}

//定义生产者类
class Producer implements Runnable{
    ArrayList<Integer> arrayList;
    Boolean flag = new Boolean(true);

    public Producer(ArrayList arrayList, boolean flag){
        this.arrayList = arrayList;
        this.flag = flag;
    }

    @Override
    public void run() {
        synchronized (arrayList) {
            if (!flag) {
                try {
                    arrayList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            arrayList.add(1);
            System.out.println("生产了一个苹果,还剩" + arrayList.size() + "个");
            flag = true;
            arrayList.notify();
        }
    }
}
这篇关于Java多线程06:线程通信的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!