精华内容
下载资源
问答
  • 2018-10-08 20:07:32

    Android应用程序开发过程中需要在子线程中刷新UI,但是刷新UI的工作只能在主线程中完成,如果强制在子线程刷新UI会导致崩溃,此时Handler机制很好地解决了这个问题
    Android系统有3种线程间通信的通信方式,分别为Handler、AsyncTask、runOnUiThread,其中AsyncTask、runOnUiThread从子线程切换到主线程刷新UI的原理是Handler机制

    1. Handler

    1.1 用法总结:

    首先定义一个继承自Handler的MyHandler并复写handleMessage方法,主线程实例化MyHandler,子线程调用Handler.sendMessage发送消息,回调主线程的Handler.handleMessage

    1.2 原理总结:

    一个线程对应一个Looper,一个Looper对应一个MessageQueue,一个MessageQueue有多个Message,每个Message最多指定一个Handler处理消息
    线程1执行Handler.sendMessage()方法,会将线程2创建的Handler保存到Message.target中,并将Message放入MessageQueue
    //Looper.prepare()方法,会new Looper()并将new MessageQueue()保存到Looper.mQueue中
    Looper.loop()方法,不断从MessageQueue中取出Message,交给Message.target(即Handler)的handleMessage处理,从而回调线程2创建的Handler复写的handleMessage方法
    //若MessageQueue为空则会使用epoll机制休眠,直到下一个Message放入MessageQueue执行nativeWake()被唤醒

    2. AsyncTask

    2.1 用法总结:

    首先定义一个继承自AsyncTask的MyAsyncTask并复写onPreExecute、doInBackground、onPostExecute方法
    主线程实例化MyAsyncTask,并调用execute方法,会依次执行onPreExecute、doInBackground、onPostExecute方法
    其中onPreExecute和onPostExecute在主线程中执行,doInBackground在子线程中执行,doInBackground在执行publishProgress时会回调到主线程执行onProgressUpdate刷新UI

    2.2 原理总结:

    执行MyAsyncTask.execute()时会在主线程执行onPreExecute,接着会使用SerialExecutor创建子线程,并在子线程中执行doInBackground,最终会执行postResult将doInBackground的
    执行结果result保存到Message中,使用Handler机制发送一个Message切换到主线程,取出result,判断当前异步任务是否已经被取消,
    如果已经被取消则会调用onCancelled()方法,如果没有被取消则会调用onPostExecute
    当在执行doInBackground的过程中如果执行publishProgress时会使用Handler机制发送一个Message切换到主线程执行onProgressUpdate刷新UI

    3. runOnUiThread

    3.1 用法总结:

    子线程执行runOnUiThread(),传入参数Runnable,并复写run方法

    3.2 原理总结:

    Handler会执行post将参数Runnable封装成一个Message并放入MessageQueue队列尾部,其中Message.callback = Runnable,Message.target = Handler
    最终执行Handler.dispatchMessage判断Message.callback是否为空,如果为空则调用Handler.handleMessage,如果不为空则调用Handler.handleCallback
    在handleCallback中调用Runnable复写的run方法,所以runOnUiThread的根本原理是Handler机制

    Android系统线程间通信的3种方式分为以下三个部分讲解:
    Android系统线程间通信方式之Handler机制
    Android系统线程间通信方式之AsyncTask机制
    Android系统线程间通信方式之runOnUiThread机制

    更多相关内容
  • 主要为大家详细介绍了Java线程间通信方式,以代码结合文字的方式来讨论线程间的通信,感兴趣的朋友可以参考一下
  • 下面小编就为大家带来一篇深入理解JAVA多线程线程间通信方式。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个...

    进程

    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

    进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。

    进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。

    进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。

    线程

    线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。

    一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程 在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。

    线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

    协程

    协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

    进程、线程、协程的区别

    概念

    对于进程来说,子进程是父进程的复制品,从父进程那里获得父进程的数据空间,堆和栈的复制品。

    而线程,相对于进程而言,是一个更加接近于执行体的概念,可以和同进程的其他线程之间直接共享数据,而且拥有自己的栈空间,拥有独立序列。

    进程、线程共同点

    它们都能提高程序的并发度,提高程序运行效率和响应时间。线程和进程在使用上各有优缺点。 线程执行开销比较小,但不利于资源的管理和保护,而进程相反。同时,线程适合在SMP机器上运行,而进程可以跨机器迁移。

    进程、线程不同点

    多进程中每个进程有自己的地址空间,线程则共享地址空间。

    所有其他区别都是因为这个区别产生的。比如说:

    1) 地址空间:线程是进程内的一个执行单元,进程内至少有一个线程,它们共享进程的地址空间,而进程有自己独立的地址空间

    2) 资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源

    3) 线程是处理器调度的基本单位,但进程不是

    4) 二者均可并发执行

    5) 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制

    1. 速度。线程产生的速度快,通讯快,切换快,因为他们处于同一地址空间。

    2. 线程的资源利用率好。

    3. 线程使用公共变量或者内存的时候需要同步机制,但进程不用。

    而他们通信方式的差异也仍然是由于这个根本原因造成的。

    线程、协程比较

    1) 一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。

    2) 线程进程都是同步机制,而协程则是异步

    3) 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态

    通信方式之间的差异

    因为那个根本原因,实际上只有进程间需要通信,同一进程的线程共享地址空间,没有通信的必要,但要做好同步/互斥,保护共享的全局变量。

    而进程间通信无论是信号,管道pipe还是共享内存都是由操作系统保证的,是系统调用。

    进程通信

    管道(pipe)

    管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

    有名管道 (namedpipe)

    有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

    信号量(semaphore)

    信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

    消息队列(messagequeue)

    消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

    信号 (sinal)

    信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

    共享内存(shared memory)

    共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

    套接字(socket)

    套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同设备及其间的进程通信。

    线程间的通信方式

    锁机制:包括互斥锁、条件变量、读写锁

    互斥锁提供了以排他方式防止数据结构被并发修改的方法。

    读写锁允许多个线程同时读共享数据,而对写操作是互斥的。

    条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。

    wait/notify 等待

    Volatile 内存共享

    CountDownLatch 并发工具

    CyclicBarrier 并发工具

    信号量机制(Semaphore)

    包括无名线程信号量和命名线程信号量。

    信号机制(Signal)

    类似进程间的信号处理。

    线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。

    展开全文
  • Android进程线程间通信方式

    千次阅读 2021-01-17 13:22:41
    线程自己基本上不拥有系统资源,只拥有一些在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。区别:(1)、一个程序至少有一个进程,一个进...

    进程:是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

    线程:是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一些在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

    区别:

    (1)、一个程序至少有一个进程,一个进程至少有一个线程;

    (2)、线程的划分尺度小于进程,使得多线程程序的并发性高;

    (3)、进程在执行过程中拥有独立的内存单元,而多个线程共享内存,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。

    ---------------------

    一、Android进程间通信方式

    1.Bundle

    由于Activity,Service,Receiver都是可以通过Intent来携带Bundle传输数据的,所以我们可以在一个进程中通过Intent将携带数据的Bundle发送到另一个进程的组件。

    缺点:无法传输Bundle不支持的数据类型。

    2.ContentProvider

    ContentProvider是Android四大组件之一,以表格的方式来储存数据,提供给外界,即Content Provider可以跨进程访问其他应用程序中的数据。用法是继承ContentProvider,实现onCreate,query,update,insert,delete和getType方法,onCreate是负责创建时做一些初始化的工作,增删查改的方法就是对数据的查询和修改,getType是返回一个String,表示Uri请求的类型。注册完后就可以使用ContentResolver去请求指定的Uri。

    3.文件

    两个进程可以到同一个文件去交换数据,我们不仅可以保存文本文件,还可以将对象持久化到文件,从另一个文件恢复。要注意的是,当并发读/写时可能会出现并发的问题。

    4.Broadcast

    Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播。

    5.AIDL方式

    Service和Content Provider类似,也可以访问其他应用程序中的数据,Content Provider返回的是Cursor对象,而Service返回的是Java对象,这种可以跨进程通讯的服务叫AIDL服务。

    AIDL通过定义服务端暴露的接口,以提供给客户端来调用,AIDL使服务器可以并行处理,而Messenger封装了AIDL之后只能串行运行,所以Messenger一般用作消息传递。

    6.Messenger

    Messenger是基于AIDL实现的,服务端(被动方)提供一个Service来处理客户端(主动方)连接,维护一个Handler来创建Messenger,在onBind时返回Messenger的binder。

    双方用Messenger来发送数据,用Handler来处理数据。Messenger处理数据依靠Handler,所以是串行的,也就是说,Handler接到多个message时,就要排队依次处理。

    7.Socket

    Socket方法是通过网络来进行数据交换,注意的是要在子线程请求,不然会堵塞主线程。客户端和服务端建立连接之后即可不断传输数据,比较适合实时的数据传输

    二、Android线程间通信方式

    一般说线程间通信主要是指主线程(也叫UI线程)和子线程之间的通信,主要有以下两种方式:

    1.AsyncTask机制

    AsyncTask,异步任务,也就是说在UI线程运行的时候,可以在后台的执行一些异步的操作;AsyncTask可以很容易且正确地使用UI线程,AsyncTask允许进行后台操作,并在不显示使用工作线程或Handler机制的情况下,将结果反馈给UI线程。但是AsyncTask只能用于短时间的操作(最多几秒就应该结束的操作),如果需要长时间运行在后台,就不适合使用AsyncTask了,只能去使用Java提供的其他API来实现。

    2.Handler机制

    Handler,继承自Object类,用来发送和处理Message对象或Runnable对象;Handler在创建时会与当前所在的线程的Looper对象相关联(如果当前线程的Looper为空或不存在,则会抛出异常,此时需要在线程中主动调用Looper.prepare()来创建一个Looper对象)。使用Handler的主要作用就是在后面的过程中发送和处理Message对象和让其他的线程完成某一个动作(如在工作线程中通过Handler对象发送一个Message对象,让UI线程进行UI的更新,然后UI线程就会在MessageQueue中得到这个Message对象(取出Message对象是由其相关联的Looper对象完成的),并作出相应的响应)。

    三、Android两个子线程之间通信

    面试的过程中,有些面试官可能会问Android子线程之间的通信方式,由于绝大部分程序员主要关注的是Android主线程和子线程之间的通信,所以这个问题很容易让人懵逼。

    主线程和子线程之间的通信可以通过主线程中的handler把子线程中的message发给主线程中的looper,或者,主线程中的handler通过post向looper中发送一个runnable。但looper默认存在于main线程中,子线程中没有Looper,该怎么办呢?其实原理很简单,把looper绑定到子线程中,并且创建一个handler。在另一个线程中通过这个handler发送消息,就可以实现子线程之间的通信了。

    子线程创建handler的两种方式:

    方式一:给子线程创建Looper对象:

    new Thread(new Runnable() {

    public void run() {

    Looper.prepare();  // 给这个Thread创建Looper对象,一个Thead只有一个Looper对象

    Handler handler = new Handler(){

    @Override

    public void handleMessage(Message msg) {

    Toast.makeText(getApplicationContext(), "handleMessage", Toast.LENGTH_LONG).show();

    }

    };

    handler.sendEmptyMessage(1);

    Looper.loop(); // 不断遍历MessageQueue中是否有消息

    };

    }).start();

    ---------------------

    方式二:获取主线程的looper,或者说是UI线程的looper:

    new Thread(new Runnable() {

    public void run() {

    Handler handler = new Handler(Looper.getMainLooper()){ // 区别在这!!!

    @Override

    public void handleMessage(Message msg) {

    Toast.makeText(getApplicationContext(), "handleMessage", Toast.LENGTH_LONG).show();

    }

    };

    handler.sendEmptyMessage(1);

    };

    }).start();

    ---------------------

    展开全文
  • 主要介绍了Python如何实现线程间通信,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
  • 线程间通信方式3:消息传递方式

    热门讨论 2013-01-18 11:01:23
    线程间通信方式3:消息传递方式的演示。采用计算演示线程的执行,并采用用户界面线程来实时显示执行的进度,线程间通信方式采用了3方式相结合,对多线程间的通信有比较好的学习和研究价值。
  • 关于线程的几控制方式以及线程中的几种通信方式,给初学者参考,希望能有用
  • 线程间通信的几实现方式

    万次阅读 多人点赞 2019-01-13 07:43:41
    线程间通信的几实现方式 首先,要短信线程间通信的模型有两:共享内存和消息传递,以下方式都是基本这两模型来实现的。我们来基本一道面试常见的题目来分析: 题目:有两个线程A、B,A线程向一个集合...

    线程间通信的几种实现方式

    首先,要短信线程间通信的模型有两种:共享内存和消息传递,以下方式都是基本这两种模型来实现的。我们来基本一道面试常见的题目来分析:
    

    题目:有两个线程A、B,A线程向一个集合里面依次添加元素"abc"字符串,一共添加十次,当添加到第五次的时候,希望B线程能够收到A线程的通知,然后B线程执行相关的业务操作


    方式一:使用 volatile 关键字

    基于 volatile 关键字来实现线程间相互通信是使用共享内存的思想,大致意思就是多个线程同时监听一个变量,当这个变量发生变化的时候 ,线程能够感知并执行相应的业务。这也是最简单的一种实现方式

    public class TestSync {
        // 定义一个共享变量来实现通信,它需要是volatile修饰,否则线程不能及时感知
        static volatile boolean notice = false;
    
        public static void main(String[] args) {
            List<String>  list = new ArrayList<>();
            // 实现线程A
            Thread threadA = new Thread(() -> {
                for (int i = 1; i <= 10; i++) {
                    list.add("abc");
                    System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (list.size() == 5)
                        notice = true;
                }
            });
            // 实现线程B
            Thread threadB = new Thread(() -> {
                while (true) {
                    if (notice) {
                        System.out.println("线程B收到通知,开始执行自己的业务...");
                        break;
                    }
                }
            });
            // 需要先启动线程B
            threadB.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 再启动线程A
            threadA.start();
        }
    }
    

    运行结果为:
    在这里插入图片描述

    方式二:使用Object类的wait() 和 notify() 方法

    众所周知,Object类提供了线程间通信的方法:wait()notify()notifyaAl(),它们是多线程通信的基础,而这种实现方式的思想自然是线程间通信。

    注意: wait和 notify必须配合synchronized使用,wait方法释放锁,notify方法不释放锁

    public class TestSync {
        public static void main(String[] args) {
            // 定义一个锁对象
            Object lock = new Object();
            List<String>  list = new ArrayList<>();
            // 实现线程A
            Thread threadA = new Thread(() -> {
                synchronized (lock) {
                    for (int i = 1; i <= 10; i++) {
                        list.add("abc");
                        System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (list.size() == 5)
                            lock.notify();// 唤醒B线程
                    }
                }
            });
            // 实现线程B
            Thread threadB = new Thread(() -> {
                while (true) {
                    synchronized (lock) {
                        if (list.size() != 5) {
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        System.out.println("线程B收到通知,开始执行自己的业务...");
                    }
                }
            });
            // 需要先启动线程B
            threadB.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 再启动线程A
            threadA.start();
        }
    }
    

    运行结果为
    在这里插入图片描述由打印结果截图可知,在线程A发出notify()唤醒通知之后,依然是走完了自己线程的业务之后,线程B才开始执行,这也正好说明了,notify()方法不释放锁,而wait()方法释放锁。

    方式三:使用JUC工具类 CountDownLatch

    jdk1.5之后在java.util.concurrent包下提供了很多并发编程相关的工具类,简化了我们的并发编程代码的书写,***CountDownLatch***基于AQS框架,相当于也是维护了一个线程间共享变量state

    public class TestSync {
        public static void main(String[] args) {
            CountDownLatch countDownLatch = new CountDownLatch(1);
            List<String>  list = new ArrayList<>();
            // 实现线程A
            Thread threadA = new Thread(() -> {
                for (int i = 1; i <= 10; i++) {
                    list.add("abc");
                    System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (list.size() == 5)
                        countDownLatch.countDown();
                }
            });
            // 实现线程B
            Thread threadB = new Thread(() -> {
                while (true) {
                    if (list.size() != 5) {
                        try {
                            countDownLatch.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("线程B收到通知,开始执行自己的业务...");
                    break;
                }
            });
            // 需要先启动线程B
            threadB.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 再启动线程A
            threadA.start();
        }
    }
    

    运行结果为:
    在这里插入图片描述

    使用 ReentrantLock 结合 Condition

    public class TestSync {
        public static void main(String[] args) {
            ReentrantLock lock = new ReentrantLock();
            Condition condition = lock.newCondition();
    
            List<String> list = new ArrayList<>();
            // 实现线程A
            Thread threadA = new Thread(() -> {
                lock.lock();
                for (int i = 1; i <= 10; i++) {
                    list.add("abc");
                    System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (list.size() == 5)
                        condition.signal();
    
                }
                lock.unlock();
            });
            // 实现线程B
            Thread threadB = new Thread(() -> {
                lock.lock();
                if (list.size() != 5) {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("线程B收到通知,开始执行自己的业务...");
                lock.unlock();
            });
            threadB.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            threadA.start();
        }
    }
    

    运行结果为:
    在这里插入图片描述
    显然这种方式使用起来并不是很好,代码编写复杂,而且线程B在被A唤醒之后由于没有获取锁还是不能立即执行,也就是说,A在唤醒操作之后,并不释放锁。这种方法跟 Objectwait()notify() 一样。

    方式五:基本LockSupport实现线程间的阻塞和唤醒

    LockSupport 是一种非常灵活的实现线程间阻塞和唤醒的工具,使用它不用关注是等待线程先进行还是唤醒线程先运行,但是得知道线程的名字。

    public class TestSync {
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            // 实现线程B
            final Thread threadB = new Thread(() -> {
                if (list.size() != 5) {
                    LockSupport.park();
                }
                System.out.println("线程B收到通知,开始执行自己的业务...");
            });
            // 实现线程A
            Thread threadA = new Thread(() -> {
                for (int i = 1; i <= 10; i++) {
                    list.add("abc");
                    System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (list.size() == 5)
                        LockSupport.unpark(threadB);
                }
            });
            threadA.start();
            threadB.start();
        }
    }
    

    运行结果
    在这里插入图片描述

    展开全文
  • 线程通信的方法主要有以下三种: 1.全局变量 进程中的线程内存共享,这是比较常用的通信方式和交互方式。 注:定义全局变量时最好使用volatile来定义,以防编译器对此变量进行优化。 Linux系统中的线程...
  • 线程间通信三种方法

    千次阅读 2018-06-14 23:08:03
    线程通信的方法主要有以下三种: 1.全局变量进程中的线程内存共享,这是比较常用的通信方式和交互方式。注:定义全局变量时最好使用volatile来定义,以防编译器对此变量进行优化。 2.Message消息机制常用的...
  • Python线程间通信方式

    千次阅读 2019-06-04 20:16:30
    1、python多线程 #! /usr/bin/evn python3 # --*-- coding: utf-8 --*-- #该实例反编译来说明函数执行流程 import dis def add(a): a = a+1 return a print(dis.dis(add)) # Python中一个线程对应于C语言中的...
  • 线程间通信方式2:参数传递方式

    热门讨论 2013-01-11 11:17:13
    线程间通信方式2:参数传递方式。通过3类线程的创建方法,演示了给线程传递方式的方式,包括;单参数、多参数和类3类。
  • 线程间通信的5种方式

    千次阅读 2021-03-10 11:39:38
    基于 volatile 关键字来实现线程间相互通信是使用共享内存的思想,大致意思就是多个线程同时监听一个变量,当这个变量发生变化的时候 ,线程能够感知并执行相应的业务。 package com.kuang.xianchengjiantongxin; ...
  • c++ 线程间通信方式

    2020-01-09 20:37:49
    一:两个进程的两个线程通信,相当于进程通信 二:一个进程中的两个线程通信  通信方式: 1.互斥锁  mutex;  lock_guard (在构造函数里加锁,在析构函数里解锁)  unique_lock自动加锁、解锁 2....
  • C例子:线程间通信

    2016-01-24 23:28:05
    该程序是我写的博客“一起talk C栗子吧(第一百一十一回:C语言实例--线程间通信)”的配套程序,共享给大家使用
  • 1,通过Handler机制 ... } } 到此这篇关于android实现线程间通信的四常见方式的文章就介绍到这了,更多相关android 线程间通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
  • Linux进程间通信-线程间通信

    千次阅读 2021-05-08 23:29:12
    1、管道管道( pipe ):管道是一半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程使用。进程的亲缘关系通常是指父子进程关系。2、 消息队列消息队列用于运行于同一台机器上的进程通信,它和...
  • java线程间通讯的几种方式

    千次阅读 多人点赞 2021-02-04 16:38:10
    这个时候就需要线程间进行通讯 A执行完了后对B说一声,喂B,我执行完了 来康康用Java怎么实现 1、基于synchronized 2、基于reentrantLock 3、基于volatile 4、基于countDownLatch 我目前就知道这四 1、...
  • Android线程间通信机制

    2021-02-27 08:58:57
    那么线程通信就会分为两情况:主线程和工作线程通信;工作线程和工作线程通信。 之所以要把这两情况给提出来,是因为基本上所有的文章都是上来直接讲主线程和普通工作线程之间的通信机制,我还没有看到过讲两...
  • 线程间通信的几种方式

    万次阅读 2018-03-06 11:21:39
    线程间通信方式①同步这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信。参考示例:public class MyObject { synchronized public void methodA() { //do something.... } ...
  • 线程间通信方式

    千次阅读 2020-09-23 21:54:23
    1、为什么需要线程通信 线程是操作系统调度的最小单位,有自己的栈空间,可以按照既定的代码逐步的执行,但是如果每个线程都孤立的运行,那就会造资源浪费。所以在现实中,我们需要这些线程可以按照指定的规则...
  • 线程间通讯方式

    千次阅读 2019-06-04 16:09:41
    线程间通讯方式 1:同步(synchronized) 2:wait/notify()机制 3:管道通信就是使用java.io.PipedInputStream 和 java.io.PipedOutputStream进行通信 进程间通讯方式 ... ...
  • 一、进程间通信(IPC,Inter-Process Communication)是指在不同进程传播或交换信息 1. 无名管道 特点 半双工(数据流向仅有一个方向),具有固定的读端和写端 只能用于父进程或兄弟线程之间通信(具有血缘关系的...
  • JAVA线程间通信的几种方式

    万次阅读 多人点赞 2017-08-12 21:55:12
    “编写两个线程,一个线程打印1~25,另一个线程打印字母A~Z,打印顺序为12A34B56C……5152Z,要求使用线程间通信。” 这是一道非常好的面试题,非常能彰显被面者关于多线程的功力,一下子就勾起了我的兴趣。这里...
  • python的多线程线程间通信方式

    千次阅读 2020-11-04 22:56:15
    线程间通信机制 >共享变量 通过共享变量来实现,简单来说就是定义一个全局变量来实现,具体示例如下: from threading import Thread from threading import currentThread def task(): global var while var: ...
  • 线程间通信及同步方法介绍

    千次阅读 2021-05-23 11:01:04
    线程间通信及同步方法介绍:一、线程间通信方式1、使用全局变量主要由于多个线程可能更改全局变量,因此全局变量最好声明为volatile。2、使用消息实现通信在Windows程序设计中,每一个线程都可以拥有自己的消息...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 426,080
精华内容 170,432
关键字:

线程间的通信方式三种