专业IT网络知识平台,分享IT百科知识、生活百科知识解答!

易企推科技
易企推科技

线程间通信的方式有哪些,线程间通信的几种方式

来源:小易整编  作者:小易  发布时间:2023-03-22 09:05
摘要:线程间通信的方式有哪些,线程间通信的几种方式一、使用同一个共享变量控制Synchronized、wait、notifypublicclassDemo1 privatefinalListLock、ConditionpublicclassT...

线程间通信的方式有哪些,线程间通信的几种方式

线程间通信的方式有哪些,线程间通信的几种方式

一、使用同一个共享变量控制Synchronized、wait、notify

public class Demo1 {    private final List

Lock、Condition

public class Task {    private final Lock lock = new ReentrantLock();    private final Condition addConditon = lock.newCondition();    private final Condition subConditon = lock.newCondition();    private volatile int num = 0;    private List

利用volatile

volatile修饰的变量值直接存在主内存里面,子线程对该变量的读写直接写住内存,而不是像其它变量一样在local thread里面产生一份copy。volatile能保证所修饰的变量对于多个线程可见性,即只要被修改,其它线程读到的一定是最新的值。

public class Demo2 {    private volatile List

利用AtomicInteger

和volatile类似

二、PipedInputStream、PipedOutputStream

这里用流在两个线程间通信,但是Java中的Stream是单向的,所以在两个线程中分别建了一个input和output

public class PipedDemo {    private final PipedInputStream inputStream1;    private final PipedOutputStream outputStream1;    private final PipedInputStream inputStream2;    private final PipedOutputStream outputStream2;    public PipedDemo(){        inputStream1 = new PipedInputStream();        outputStream1 = new PipedOutputStream();        inputStream2 = new PipedInputStream();        outputStream2 = new PipedOutputStream();        try {            inputStream1.connect(outputStream2);            inputStream2.connect(outputStream1);        } catch (IOException e) {            e.printStackTrace();        }    }    /**程序退出时,需要关闭stream*/    public void shutdown() throws IOException {        inputStream1.close();        inputStream2.close();        outputStream1.close();        outputStream2.close();    }    public static void main(String[] args) throws IOException {        PipedDemo demo =new PipedDemo();        new Thread(()->{            PipedInputStream in = demo.inputStream2;            PipedOutputStream out = demo.outputStream2;            for (int i = 0; i < 10; i++) {                try {                    byte[] inArr = new byte[2];                    in.read(inArr);                    System.out.print(Thread.currentThread().getName()+": "+i+" ");                    System.out.println(new String(inArr));                    while(true){                        if("go".equals(new String(inArr)))                            break;                    }                    out.write("ok".getBytes());                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();        new Thread(()->{            PipedInputStream in = demo.inputStream1;            PipedOutputStream out = demo.outputStream1;            for (int i = 0; i < 10; i++) {                try {                    out.write("go".getBytes());                    byte[] inArr = new byte[2];                    in.read(inArr);                    System.out.print(Thread.currentThread().getName()+": "+i+" ");                    System.out.println(new String(inArr));                    while(true){                        if("ok".equals(new String(inArr)))                            break;                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();//        demo.shutdown();    }}

输出

Thread-0: 0 goThread-1: 0 okThread-0: 1 goThread-1: 1 okThread-0: 2 goThread-1: 2 okThread-0: 3 goThread-1: 3 okThread-0: 4 goThread-1: 4 okThread-0: 5 goThread-1: 5 okThread-0: 6 goThread-1: 6 okThread-0: 7 goThread-1: 7 okThread-0: 8 goThread-1: 8 okThread-0: 9 goThread-1: 9 ok

三、利用BlockingQueue

BlockingQueue定义的常用方法如下:

  • add(Object):把Object加到BlockingQueue里,如果BlockingQueue可以容纳,则返回true,否则抛出异常。

  • offer(Object):表示如果可能的话,将Object加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false。

  • put(Object):把Object加到BlockingQueue里,如果BlockingQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里有空间再继续。

  • poll(time):获取并删除BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null。当不传入time值时,立刻返回。

  • peek():立刻获取BlockingQueue里排在首位的对象,但不从队列里删除,如果队列为空,则返回null。

  • take():获取并删除BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的对象被加入为止。

BlockingQueue有四个具体的实现类:

  • ArrayBlockingQueue:数组阻塞队列,规定大小,其构造函数必须带一个int参数来指明其大小。其所含的对象是以FIFO(先入先出)顺序排序的。

  • LinkedBlockingQueue:链阻塞队列,大小不定,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定。其所含的对象是以FIFO顺序排序的。

  • PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。

  • SynchronousQueue:特殊的BlockingQueue,它的内部同时只能够容纳单个元素,对其的操作必须是放和取交替完成的。

  • DelayQueue:延迟队列,注入其中的元素必须实现 java.util.concurrent.Delayed 接口

所有BlockingQueue的使用方式类似,以下例子一个线程写入,一个线程读取,操作的是同一个Queue:

public class BlockingQueueDemo {    public static void main(String[] args) {        LinkedBlockingQueue


本文地址:IT问答频道 https://www.hkm168.com/itwenda/936767.html,易企推百科一个免费的知识分享平台,本站部分文章来网络分享,本着互联网分享的精神,如有涉及到您的权益,请联系我们删除,谢谢!


IT问答
小编:小易整编
相关文章相关阅读
  • win10电脑如何关闭超线程

    win10电脑如何关闭超线程

    1、在电脑上打开开始菜单,找到系统配置选项,并点击打开。2、在跳转的界面中,点击上方的引导选项。3、在打开的引导界面中,找到高级选项,并点击打开。4、在打开的高级选项中,找到处理器个数,并选择为一个。5、设置完成后,点击下方的确定选项即可完...

  • 进程和线程是什么

    进程和线程是什么

    进程是资源分配的基本单位,它是程序执行时的一个实例,在程序运行时创建;线程是程序执行的最小单位,是进程的一个执行流,一个线程由多个线程组成的。什么是进程进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会...

  • 进程和线程是什么

    进程和线程是什么

    进程是资源分配的基本单位,它是程序执行时的一个实例,在程序运行时创建;线程是程序执行的最小单位,是进程的一个执行流,一个线程由多个线程组成的。什么是进程进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会...

  • 核心数和线程数是什么意思

    核心数和线程数是什么意思

    核心数指的是cpu内核数量,表示一个cpu由多少个核心组成;cpu核心是cpu的重要组成部件,在内核频率、缓存大小等条件相同的情况下,cpu核心数量越多,cpu的整体性能越强。线程数是一种逻辑的概念,简单地说,就是模拟出的cpu核心数。cp...

  • 多线程是什么意思

    多线程是什么意思

    线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位,而多线程就是指从软件或者硬件上实现多个线程并发执行的技术,具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。线程是...

  • PHP中的多线程

    PHP中的多线程

    在php编程中,如果我们需要执行多个任务或同时处理多个请求,多线程是一种非常重要的编程技术。多线程可以实现多个线程同时运行,提高程序效率,提升用户体验。一、PHP多线程介绍PHP多线程是指同时执行两个或多个线程的程序,每个线程都是一个独立的...

  • 线程和进程的区别是什么

    线程和进程的区别是什么

    线程和进程的区别:1、线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小;2、进程相对独立,需要通过显式机制进行通信,切换开销较大;而线程的管理更为灵活,进程的管理相对复杂。线程和进程是操作系统中...

  • superpi,superpi支持多核和多线程吗一般的多核cpu跑superpi用到...

    superpi,superpi支持多核和多线程吗一般的多核cpu跑superpi用到了多核还

    1,superpi支持多核和多线程吗一般的多核cpu跑superpi用到了多核还superpi只支持单线程~就是只用一个核心来计算多核无优势~CPU频率越高就算的越快你好!这个是单核的。如果要多线程,请跑wPrime和Fritz仅...

  • 周排行
  • 月排行
  • 年排行

精彩推荐