精华内容
下载资源
问答
  • 主要介绍了Java Socket实现单线程通信的方法,结合具体实例形式分析了java socket单线程通信的原理与客户端、服务器端相关实现技巧,需要的朋友可以参考下
  • 线程和queue配合使用,实现子线程和主线程相互通信的例子 ''' import threading __author__ = "Kenny.Li" import Queue import time import random q = Queue.Queue() class MyThread(threading.Thread): def __...
  • Python使用UDP实现单线程通信

    万次阅读 2021-06-04 10:55:44
    Python使用UDP实现单线程通信 先声明一下,本人是学习web方向,这篇文章是关于我在学校学习python的时候学到一个比较有意思的东西,所以写来分享一下,并非专业python学生,不足之处欢迎指正 ! 首先我们先了解一下...

    Python使用UDP实现单线程通信

    先声明一下,本人是学习web方向,这篇文章是关于我在学校学习python的时候学到一个比较有意思的东西,所以写来分享一下,并非专业python学生,不足之处欢迎指正 !

    首先我们先了解一下socket

    socket简称套接字,是进程间通信的一种方式。与其他的方式的进程间的通讯的方式不同的是,socket是实现了主机间进程间的通讯。我们网络上的各种服务都是基于socket来完成的。例如QQ.微信。

    关于UDP

    udp—–数据报文协议,是一个无连接的简单的面向数据报的运输层协议,UDP不提供可靠性,他只是将应用程序传送给IP层的数据报文发送出去,并不保证能否达到目的地。由于UDP在传输的过程中不需要和服务器建立链接。且没有超时重发的的机制。故而传输很快。
    如图;
    在这里插入图片描述
    通过这张图我们来看代码就明了多了
    服务器端源码:

    import socket
    
    serverSocket = socket.socket()
    serverSocket.bind(('127.0.0.1',12345))
    serverSocket.listen(5)
    print("等待客户端发起请求")
    while True:
        conn,addr = serverSocket.accept()
        print("客户端连接成功,等待对方响应中 !")
        while True:
            try:
                recv_data = conn.recv(1024)
                if len(recv_data) == 0:
                    print("服务器: 退出连接")
                    break
                print("客户端: "+ str(recv_data.decode()))
                send_data = input("请输入你的回应: ")
                conn.send(bytes(send_data,encoding='UTF-8'))
                print("正在等待客户端回应: ")
            except Exception:
                break
        conn.close()
    

    客户端源码:

    import socket
    
    clientSocket = socket.socket()
    clientSocket.connect(('127.0.0.1', 12345))
    while True:
        send_data = input("客户端: ")
        if send_data == 'exit':
            print("客户端: 退出连接")
            break
        if len(send_data) == 0:
            continue
        clientSocket.send(bytes(send_data, encoding='utf-8'))
        print("正在等待服务器回应: ")
        recv_data = clientSocket.recv(1024)
        print("服务器: "+str(recv_data.decode()))
    clientSocket.close()
    

    运行截图:
    在这里插入图片描述

    最后说明一下

    本代码仅限单线程,即一个人只能说一句话然后等待对方回应,后续我会学习一下关于群聊的方式,就是多线程聊天,目前还不会。
    最后如果能帮助到你,点个赞支持一下博主吧!
    在这里插入图片描述

    展开全文
  • java socket tcpip多线程网络通信服务器客户端
  • 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的, 即不同的线程可以执行同样的函数。 什么是多线程? 多线程是指程序中包含多个执行流,即在一个程序中可以同时...

    什么是进程?
    当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。
    而一个进程又是由多个线程所组成的。


    什么是线程?
    线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,
    即不同的线程可以执行同样的函数。


    什么是多线程?
    多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,
    也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。


    多线程的好处:
    可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,
    这样就大大提高了程序的效率。 


    多线程的不利方面:
    线程也是程序,所以线程需要占用内存,线程越多占用内存也越多; 
    多线程需要协调和管理,所以需要CPU时间跟踪线程; 
    线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
    线程太多会导致控制太复杂,最终可能造成很多Bug;


    多线程与单线程的区别
    生活举例
    你早上上班,正要打卡的时候,手机响了。。你如果先接了电话,等接完了,在打卡,就是单线程。
    如果你一手接电话,一手打卡。就是多线程。
    2件事的结果是一样的。。你接了电话且打了卡。

     

    多线程处理的优点

    同步应用程序的开发比较容易,但由于需要在上一个任务完成后才能开始新的任务,所以其效率通常比多线程应用程序低。如果完成同步任务所用的时间比预计时间长,应用程序可能会不响应。多线程处理可以同时运行多个过程。例如,文字处理器应用程序在您处理文档的同时,可以检查拼写(作为单独的任务)。由于多线程应用程序将程序划分成独立的任务,因此可以在以下方面显著提高性能: 
    多线程技术使程序的响应速度更快,因为用户界面可以在进行其他工作的同时一直处于活动状态。 
    当前没有进行处理的任务可以将处理器时间让给其他任务。 
    占用大量处理时间的任务可以定期将处理器时间让给其他任务。 
    可以随时停止任务。 
    可以分别设置各个任务的优先级以优化性能。 

    是否需要创建多线程应用程序取决于多个因素。在以下情况下,最适合采用多线程处理:
    耗时或大量占用处理器的任务阻塞用户界面操作。 
    各个任务必须等待外部资源(如远程文件或 INTERNET 连接)。 

    例如,用于跟踪 WEB 页上的链接并下载满足特定条件的文件的 INTERNET 应用程序“ROBOT”。这种应用程序可以依次同步下载各个文件,也可以使用多线程同时下载多个文件。多线程方法比同步方法的效率高很多,因为即使在某些线程中远程 WEB 服务器的响应非常慢,也可以下载文件。

    下面是多线程的例子
    还在DOS时代,人们就在寻求一种多任务的实现。于是出现了TSR类型的后台驻留程序,比较有代表性的有SIDE KICK、VSAFE等优秀的TSR程序,这类程序的出现和应用确实给用户使用计算机带来了极大的方便,比如SIDE KICK,们编程可以在不用进编辑程序的状态下,一边编辑源程序,一边编译运行,非常方便。但是,DOS单任务操作系统的致命缺陷注定了在DOS下不可能开发出真正的多任务程序。进入WINDOWS3.1时代,这种情况依然没有根本的改变,一次应用只能做一件事。比如数据库查询,除非应用编得很好,在查询期间整个系统将不响应用户的输入。
     进入了WINDOWS NT和WINDOWS 9X时代,情况就有了彻底的改观,操作系统从真正意义上实现了多任务(严格地说,WIN9X还算不上)。一个应用程序,在需要的时候可以有许多个执行线程,每个线程就是一个小的执行程序,操作系统自动使各个线程共享CPU资源,确保任一线程都不能使系统死锁。这样,在编程的时候,可以把费时间的任务移到后台,在前台用另一个线程接受用户的输入。对那些对实时性要求比较高的编程任务,如网络客户服务、串行通信等应用时,多线程的实现无疑大大地增强了程序的可用性和稳固性。

    =====================================================================================

    坏处:增加了调度和管理的开销,带来了一些不确定性,需要复杂的同步机制,避免死锁等等。
    好处:一定程度上提高响应速度,在多核的情况下还是更能充分利用CPU资源的。

    =====================================================================================

    单线程的也就是程序执行时,所跑的程序路径(处理的东西)是连续顺序下来的,必须前面的处理好,后面的才会执行到。   
    (未细看)单线程和多线程的优缺点 - Daniel - 休子的博客       多线程嘛,举个例子也就是说程序可以同时执行2个以上相同类似的操作,比如一些搜索代理或者群发email的多线程软件,由于操作一次需要网络的返回信息   花的时间比较长,而对cpu来说却是空闲的,如果是一个一个顺序执行,那么搜索几千个IP就会花上好久好久。   而如果用多线程就可以在等待期间   加入其他的搜索,然后等待,这样可以提高效率。不过多线程和多进程公用一些资源时要考虑的问题好像也是一样的,对于一些公共资源或者公共变量的访问和修改时要注意特别的,需要一些锁定什么的,还有顺序问题的考虑。  
           多线程编程的目的,就是"最大限度地利用CPU资源",当某一线程的处理不需要占用CPU而只和I/O,OEMBIOS等资源打交道时,让需要占用CPU资源的其它线程有机会获得CPU资源。每个程序执行时都会产生一个进程,而每一个进程至少要有一个主线程。这个线程其实是进程执行的一条线索,除了主线程外你还可以给进程增加其它的线程,也即增加其它的执行线索,由此在某种程度上可以看成是给一个应用程序增加了多任务功能。当程序运行后,您可以根据各种条件挂起或运行这些线程,尤其在多CPU的环境中,这些线程是并发运行的。多线程就是在一个进程内有多个线程。从而使一个应用程序有了多任务的功能。多进程技术也可以实现这一点,但是创建进程的高消耗(每个进程都有独立的数据和代码空间),进程之间通信的不方便(消息机制),进程切换的时间太长,这些导致了多线程的提出,对于单CPU来说(没有开启超线程),在同一时间只能执行一个线程,所以如果想实现多任务,那么就只能每个进程或线程获得一个时间片,在某个时间片内,只能一个线程执行,然后按照某种策略换其他线程执行。由于时间片很短,这样给用户的感觉是同时有好多线程在执行。但是线程切换是有代价的,因此如果采用多进程,那么就需要将线程所隶属的该进程所需要的内存进行切换,这时间代价是很多的。而线程切换代价就很少,线程是可以共享内存的。所以采用多线程在切换上花费的比多进程少得多。但是,线程切换还是需要时间消耗的,所以采用一个拥有两个线程的进程执行所需要的时间比一个线程的进程执行两次所需要的时间要多一些。即采用多线程不会提高程序的执行速度,反而会降低速度,但是对于用户来说,可以减少用户的响应时间。上述结果只是针对单CPU,如果对于多CPU或者CPU采用超线程技术的话,采用多线程技术还是会提高程序的执行速度的。因为单线程只会映射到一个CPU上,而多线程会映射到多个CPU上,超线程技术本质是多线程硬件化,所以也会加快程序的执行速度。

    ====================================================================================

    如果线程出现死锁,唯一能证明的就是应用程序有问题,这并不是线程的缺点。

    线程相对于进程的优点:
    1、开销小
    2、资源共享性好。

    线程相对于进程的缺点:
    1、共享资源需要耗费一定的锁资源,同步相对复杂。
    2、一个线程崩溃可能导致整个进程崩溃,这个当然是自己的应用程序有问题

    ====================================================================================

    CPU是以时间片的方式为进程分配CUP处理时间的,当一个进程以同步的方式去完成几件事情时,此进程必须完成了第一件事情以后再做第二件事,如此按顺序地向CPU请求完成要做的事情。在此单线程的工作模式下,如果把CUP看作是一共有100个时间片的话,CPU可能一直都只是花了其中的10个时间片来处理当前进程所要做的事情,只是用到了CPU的10%的时间片,而其他时间都白白浪费了,当然,实际上CPU的工作模式还是做完一件事以后再去做另一件事,只是CUP的处理速度非常快,很快就处理完成所请求的情事。

        为了提高CPU的使用率,采用多线程的方式去同时完成几件事情而互不干扰,如当前进程要完成三件事情1、2、3,那么CPU会分别用10%的时间来同时处理这3件事情,从而让CPU的使用率达到了30%,大大地提高了CPU的利用率。多线程的好处在处理一些特殊的场合其优势尤其明显。比如下载文件,你要一边下载一边显示进度一边保存,在这种情况下,如果没有用多线程的话,没有意外的话一般都会把主线程阻塞,比如进度条的进度根本没有随着已下载的量而变化,堪至是整个窗体都动不了,用多线程就可以很好地解决这个问题。

        这里有一个生活实例可能更好地去理解多线程:回去看你女朋友做饭,正常的话她都会把洗好的菜(肉)先放到锅里煮,然后一边洗别的菜或处理别的事情,如:洗碗、收拾桌台准备开饭,人还是一个人,但她同时做几件事情,这样就可以大大地提高效率。总的一句话就是:CPU还是要花同样多的时间去完成所有的事情,但多线程可以让CPU掺插地同时做多件事情,在视觉上让用户觉得计算机在同时帮他处理多件事情,更好地改善用户体验。

         了解了多线程的好处以后,就要了解应该在什么样的情况下使用多线程技术。因为并不是说所有情况下用多线程都是好事,因为多线程的情况下,CPU还要花时间去维护,CPU处理各线程的请求时在线程间的切换也要花时间,所以一般情况下是可以不用多线程的,用了有时反而会得不偿失。大多情况下,要用到多线程的主要是需要处理大量的IO操作时或处理的情况需要花大量的时间等等,比如:读写文件、视频图像的采集、处理、显示、保存等。

     

    转载于:http://blog.csdn.net/u012134199/article/details/46290465

    展开全文
  • Java编写的简易socket通信,既有单线程socket通信也有多线程socket通信,使用Java原生sdk实现,可以运行。
  • 主要为大家详细介绍了java实现Socket通信单线程服务,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 2.首先在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。 3.Handler: (1).概念: Handler是沟通Activity 与Thread/runnable的桥梁。而Handler是...
  • 简单大循环 单线程实现通信 1. TCP连接通信 2. Server先监听,等待Client连接 3. 双方都可以发"Stop!"停止通信,但此程序Client只会停止,Server可以一直监听,即断开后,Client可以再次连接 4. 不能一对多通信,...
  • Android多线程通信机制

    千次阅读 2018-04-10 11:32:40
    在Android中我们把UI线程外的线程成为...这就需要掌握线程通信方式。 Androiod提供了两种线程通信方式:一种是AsyncTask机制,另一种是Handler机制。 1.线程通信方式之AsyncTask机制: AsyncTask异步任务...

    在Android中我们把UI线程外的线程成为工作线程。我们不能再主线程中做耗时操作,如网络廉连接,IO操作。
    因此我们可以把耗时操作放到另一个线程中去做,操作完成后再通知主线程做相应响应。这就需要掌握线程间通信方式。
    Androiod提供了两种线程间通信方式:一种是AsyncTask机制,另一种是Handler机制。

    1.线程间通信方式之AsyncTask机制:
    AsyncTask异步任务,也就是说在线程运行的时候,也可以在后台执行一些异步的操作。
    AsyncTask允许进行后台操作,并在不显示使用工作线程和Handler机制情况下,将结果返回给UI线程。AsyncTask只适用于短时间的操作。

    1.1AsyncTask使用
    AsyncTask只能通过继承使用:

    
     private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {   //处理异步任务的方法,是在工作线程中执行的,必须实现这个方法
         protected Long doInBackground(URL... urls) {
             int count = urls.length;
             long totalSize = 0;
             for (int i = 0; i < count; i++) {
                 totalSize += Downloader.downloadFile(urls[i]);
                 publishProgress((int) ((i / (float) count) * 100));
                 // Escape early if cancel() is called
                 if (isCancelled()) break;
             }
             return totalSize;
         }
        //更新后台任务的完成进度,可随时向UI线程反馈执行进度,方法是在UI线程中执行的
         protected void onProgressUpdate(Integer... progress) {
             setProgressPercent(progress[0]);
         }
        //任务的最终结果,这个方法是在UI线程中执行的,
         protected void onPostExecute(Long result) {
             showDialog("Downloaded " + result + " bytes");
         }
     }

    AsyncTask的几个参数:
    Params:要执行的任务的参数类型
    Progress:后台执行任务的进度
    Result:后台执行任务的最终结果

    当一个AsyncTask任务执行时,它会经历四个步骤:
    onPreExecute():
    任务执行前调用,用来做一些UI初始化工作,在UI线程中执行
    doInBackground():
    后台执行任务,工作线程中执行
    onProgressUpdate():
    更新正在后台执行任务的进度,在主线程中工作,可用来通知用户任务现在的完成进度,在调用这个方法前,需要在第2个步骤里调用 publishProgress(Progress…)将进度传递给这个方法;
    onPostExecute():
    在后台任务完成后,会将结果返回给这个方法,在UI线程中调用,可以更新UI;

    在使用AsyncTask的时候,需要注意的地方:

    AsyncTask类必须在UI线程中加载,这在在Android Jelly_Bean版本后这些都是自动完成的;

    AsyncTask类必须在UI线程中实例化;

    不要手动去调用onPreExecute(),doInBackground(Params…),publishProgress(Progress…),onPostExecute(Result)方法,这些方法都会由系统自动去调用。

    execute(Params…)方法必须在UI线程中调用,如在UI线程中执行这个语句:new DownloadFilesTask().execute(url1, url2, url3);我们不需要做其他的工作,这个下载任务就会自动在后台执行了,并且AsynacTask任务只能执行一次;

    2.线程间通信方式之Handler机制:*
    Handler,发送和处理Message对象和Runnable对象;
    Looper,用于从MessageQueue中取出消息(Message)对象,并发送给Handler处理;
    MessageQueue:消息队列,用于存放Handler发布的消息;
    Message:消息的类型,里面包含几个实例对象;

    what,用户定义的int型消息代码,用来描述消息;
    obj,随消息发送的用户指定对象;
    target,处理消息的Handler;
    一个Handler仅与一个Looper相关联,一个Message也仅与一个目标Handler对象相关联,一个Looper对象拥有一个MessageQueue,但多个不同的Handler对象也可以与同一个对象相关联。也就是说,Handler可以共享一个MessageQueue,从而达到消息共享的目的。者也是Android通过Handler机制实现多线程间通信的原理。

    上面说到Handler对象仅与一个Looper相关联,那么这个关联是什么时候实现的呢?答案是:Handler对象创建的时候。UI线程在创建的时候就拥有一个Handler对象和一个Looper对象。(工作线程需要自己调用Looper.prepare()来创建一个Looper对象),然后任何在主线程中创建的Handler对象都会默认与主线程的Looper对象相关联。(Handler对象创建的时候,会与这个线程的Looper对象相关联)。进而我们就可以把在UI主线程中创建的Handler传递给工作线程,那么在工作线程中用这个Handler对象处理的消息就是就是在UI主线程的MessageQueue中处理的。

    了解了使用Handler机制来实现Android线程间异步通信的原理,下面我们再来详细了解下这四个核心类;

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

    Handler用post来完成发送Runnable对象工作,用sendMessage来发送消息;
    post允许把一个Runnable对象发送到消息队列中,它的方法有:
    post(Runnable),postDelayed(Runnable,long),postAtTime(Runnable,long);
    handler用sendMessage把Message对象发送到消息队列,它的方法有:
    sendEmptyMessage(int),sendMessage(Message),sendMessageDelayed(Message,long),sendMessageAtTime(Message,long);

    如果Handler是通过post体系将Runnable对象发送到MessageQueue队列中,则这个Runnable对象的run()方法是运行在Handler对象创建时所在线程;
    如果Handler是通过sendMessage体系将Message发送到MessageQueue中,则需要重写handleMessage()方法来获取工作线程传递过来的Message对象,handleMessage()方法是工作在Handler对象建立时所在的线程的。

    2.2Mssage
    Message用来定义一个
    包含任意数据的消息对象,这个对象可以被发送给 Handler处理。我们最好通过Message.obtain()或Handler.obtainMessage()来获取一个Message对象(通过这两个方法得到的对象是从对象回收池中得到,也就是说是复用已经处理完的Message对象,而不是重新生成一个新对象),如果通过Message的构造方法得到一个Message对象,则这个对象是重新生成的。

    Message{
    int arg1;//如果我们只需要存储一些简单的Integer数据,则可通过设置这个属性来传递
    int agr2;//使用同arg1
    Object obj; //设置需要发送给接收方的对象,这个对象需要实现序列化接口
    int what; //描述这个消息的标识;
    //设置与这个消息对应的任意数据,这个数据是用Bundle封装的;
    void setData(Bundle data);
    Bundle getData(); 得到与这个消息对应的数据信息;
    //省略了方法和可选的属性
    ......

    2.3MessageQueue
    MessageQueue保存由Looper调度的消息列表,消息通过与Looper相关联的Handler对象添加进MessageQueue。
    2.4Looper
    Looper为线程运行一个消息的循环队列,主要就是完成Message与Handler交互功能。需要注意的是线程默认并不会给我们提供一个一个Looper实例来管理消息队列,我们需要在线程中主动调用Looper.prepare()方法来实例化一个Looper对象,用于管理消息队列;Looper对象会不断的去判断MessageQueue是否为空,如果不空,则将Message取出给相应的Handler处理;如果为空,Looper就会进入阻塞状态,直到有新的消息进入MessageQueue。

    其实,说白了,Android中通过Handler机制来异步处理多线程间的通信就是多个线程间共享一个MessageQueue,工作线程将Message发送到MessageQueue,然后UI线程或其他线程在MessageQueue中取出,进行相应处理。

    补充说明:
    子线程更新UI的四种方法:
    1.handlr.post(Runnable r)
    2.handler.handlerMessage(Message msg)
    3.runOnUiThread(Runnable r)
    4.View.post(Runnable r)

    展开全文
  • 本周的学习计划是Android通信模块,内容:单线程,多线程通信方式,Handler 与UI Thread的交互,Handler接合子线程的使用。 二丶效果演示(源码链接见文末) 三丶实现功能 1.演示使用Handler常见崩溃 2....

    本文出自:http://blog.csdn.net/dt235201314/article/details/73823653

    一丶概述

    本周的学习计划是Android通信模块,内容:单线程,多线程通信方式,Handler 与UI Thread的交互,Handler接合子线程的使用。

    二丶效果演示(源码链接见文末)


    三丶实现功能

    1.演示使用Handler常见崩溃

    2.handler更新TextView的UI

    3.实现图片轮播及停止

    4.输出handleMessage(Message mes)的mes打印

    5.自定义线程相关handler测试执行

    6.Handler异步消息处理测试

    handler相关方法运用

    四丶正文

    1.选说说多线程(工作到现在用的不太多,都是别人封装好的框架直接用)

    入门文章 菜鸟教程:Java多线程编程

    2.Handler

    最初学习Handler是通过扣丁学堂,之前的文章:扣丁学堂——Handler

    后面在开发扣丁音乐闪屏页面延时跳转功能时也有用到Handler。文章链接:扣丁音乐(一)——闪屏页SplashActivity(欢迎界面)

    最近开发用到的SwipeRefreshLayout 的onRefresh()方法,也常看到handler

    @Override
    public void onRefresh() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                mEntities.clear();
                intData();
                //★3.通知recycleView改变了数据
                homeAdapter.notifyDataSetChanged();
                //★4.记得关闭刷新,否则刷新球一直在转
                mSwipeRefreshLayout.setRefreshing(false);
            }
        }, 50);
    }
    以上基本是在整理文章前关于handler的所有运用。

    好了,现在重新认识

    2.Handler类的引入:

    3.Handler的执行流程图:

    流程图解析: 
    相关名词

    • UI线程:就是我们的主线程,系统在创建UI线程的时候会初始化一个Looper对象,同时也会创建一个与其关联的MessageQueue;
    • Handler:作用就是发送与处理信息,如果希望Handler正常工作,在当前线程中要有一个Looper对象
    • Message:Handler接收与处理的消息对象
    • MessageQueue:消息队列,先进先出管理Message,在初始化Looper对象时会创建一个与之关联的MessageQueue;
    • Looper:每个线程只能够有一个Looper,管理MessageQueue,不断地从中取出Message分发给对应的Handler处理!

    简单点说:

    当我们的子线程想修改Activity中的UI组件时,我们可以新建一个Handler对象,通过这个对象向主线程发送信息;而我们发送的信息会先到主线程的MessageQueue进行等待,由Looper按先入先出顺序取出,再根据message对象的what属性分发给对应的Handler进行处理!



    4.Handler的相关方法:

    • void handleMessage(Message msg):处理消息的方法,通常是用于被重写!
    • sendEmptyMessage(int what):发送空消息
    • sendEmptyMessageDelayed(int what,long delayMillis):指定延时多少毫秒后发送空信息
    • sendMessage(Message msg):立即发送信息
    • sendMessageDelayed(Message msg):指定延时多少毫秒后发送信息
    • final boolean hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息 
      如果是参数为(int what,Object object):除了判断what属性,还需要判断Object属性是否为指定对象的消息

    5.看代码

    1.非UI线程线程更新UI崩溃测试:

    case R.id.id_btn1:
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000 * 3);
                    idTv.setText("蹦啦");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
        break;
    case R.id.id_btn2:
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000 * 3);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            idTv.setText("又长帅了");
                        }
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
        break;

    关于这里有个小插曲,涉及源码解读,观看爱哥博客

    为什么我们可以在非UI线程中更新UI


    2.循环播放图片及停止

    Handler handler = new Handler();
    Thread myThread = new Thread(){
        @Override
        public void run() {
            index++;
            index = index%3;
            System.out.println(index);
            idImg.setImageResource(images[index]);
            handler.postDelayed(myThread,1000);
        }
    };
    点击事件

    case R.id.id_btn3:
        handler.postDelayed(myThread,1000);
        break;
    case R.id.id_btn4:
        handler.removeCallbacks(myThread);

    handler.postDelayed(X,X)是延迟执行线程

    handler.removeCallbacks(X)移除线程中所有消息和回调


    3.handle传递message可携带的内容有(int 实体内等)

    Handler customHander = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            idTv.setText("msg.arg1>"+msg.arg1+ "\nmsg.arg2>" +msg.arg2 +"\nmsg.obj>"+((Person)msg.obj).toString());
        }
    };
    点击事件

                case R.id.id_btn5:
                    Person dog=new Person("金三胖",1);
    //                Message message = new Message();
                    Message message= customHander.obtainMessage();
                    message.arg1 = 1;
                    message.arg2 = 2;
                    message.obj = dog;
    //                customHander.sendMessage(message);
                    message.sendToTarget();
                    break;

    4.消息拦截测试

    Handler interceptHander = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            Toast.makeText(HandlerDemoActivity.this, "callback handleMessage", Toast.LENGTH_SHORT).show();
            System.out.println("is intercept Handler>"+msg.what);
            // 设置true拦截消息
            return true;
        }
    }){
        @Override
        public void handleMessage(Message msg) {
            System.out.println("is intercept Handler");
        }
    };
    点击事件

    case R.id.id_btn6:
        interceptHander.sendEmptyMessage(1);
        break;
    5.子线程中实例化hangler崩溃测试

      case R.id.id_btn7:
                    new Thread() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(1000*3);
    //                    idTv.setText("UI线程更新UI会出现什么异常呢?");
                                new Handler().post(new Runnable() {
                                    @Override
                                    public void run() {
                                        idTv.setText("又蹦啦");
                                    }
                                });
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }.start();
                    break;
    6.自定义一个与线程相关Handler

    public class HandlerActivity extends AppCompatActivity {
        private MyThread myThread;
        private Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                System.out.println("UI ==:"+ Thread.currentThread());
            }
        };
    
        class MyThread extends Thread {
            public Handler handler;
            @Override
            public void run() {
                Looper.prepare();
                handler= new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        System.out.println("currentThread:=="+ Thread.currentThread());
                    }
                };
                Looper.loop();
            }
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_handler);
            myThread = new MyThread();
            myThread.start();
            try {
                Thread.sleep(1000*5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            myThread.handler.sendEmptyMessage(1);
            handler.sendEmptyMessage(1);
        }
    }
    
    效果打印:

    06-29 17:07:30.519 9652-11848/com.example.jinboy.codertodeveloperbytcler I/System.out: currentThread:==Thread[Thread-9681,5,main]
    06-29 17:07:30.659 9652-9652/com.example.jinboy.codertodeveloperbytcler I/System.out: UI ==:Thread[main,5,main]


    7.Handler异步消息处理

    public class HandlerThreadActivity extends AppCompatActivity implements View.OnClickListener {
        private Button idBtn1,idBtn2;
        private Handler threadhandler;
        private HandlerThread thread;
    
        Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                System.out.println("UI thread==>" + Thread.currentThread());
                // 给主线程发送消息
                Message message = new Message();
                message.what =1;
                threadhandler.sendMessageDelayed(message, 1000);
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_handler_thread);
            idBtn1 = (Button) findViewById(R.id.id_btn1);
            idBtn2 = (Button) findViewById(R.id.id_btn2);
            idBtn1.setOnClickListener(this);
            idBtn2.setOnClickListener(this);
            thread = new HandlerThread("Handler Thread");
            thread.start();
            threadhandler = new Handler(thread.getLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    // 处理耗时操作
                    System.out.println("current thread==>" + Thread.currentThread());
                    // 给主线程发送消息
                    Message message = new Message();
                    message.what =1;
                    handler.sendMessageDelayed(message, 1000);
                }
            };
    //        threadhandler.sendEmptyMessage(1);
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.id_btn1:
                    handler.sendEmptyMessage(1);
                    break;
                case R.id.id_btn2:
                    handler.removeMessages(1);
                    threadhandler.removeMessages(1);
                    break;
            }
        }
    }
    
    打印输出


    五丶参考链接和拓展学习

    参考内容:

    小猪博客:http://my.csdn.net/zpj779878443

    慕课网课程-Android面试常客Handler详解

    Android异步消息处理机制完全解析-Handler详解

    拓展学习:

    40个Java多线程问题总结

    android进行异步更新UI的四种方式

    Handler源码解析

    HandlerThread的使用以及原理

    Android HandlerThread 完全解析

    Android异步消息处理机制完全解析,带你从源码的角度彻底理解

    六丶日常开发案例

    1.Android避免在主线程进行网络请求和UI操作

    方法一:线程请求网络+Handler更新UI

    //handler 处理返回的请求结果
    handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bundle data = msg.getData();
            String val = data.getString("value");
            tv_name.setText(tvName);
            tv_originalArticleNumber.setText(tvOriginalArticleNumber);
            tv_visitNumber.setText(tvVisitNumber);
            tv_mark.setText(tvMark);
            tv_rank.setText(tvRank);
            Log.i("mylog", "请求结果-->" + val);
        }
    };
    
    //新线程进行网络请求
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            BlogAuthor blogAuthor = JsoupUtil.getBlogAutoMessage();
            tvName = blogAuthor.getAuthorName() + "\n" + blogAuthor.getCode()
                    + "\n" + blogAuthor.getMyHelloWorld();
            tvOriginalArticleNumber = blogAuthor.getOriginalArticleNumber();
            tvVisitNumber = blogAuthor.getVisitNumber();
            tvMark = blogAuthor.getMark();
            tvRank = blogAuthor.getRank();
            Message msg = new Message();
            Bundle data = new Bundle();
            data.putString("value", "请求结果");
            msg.setData(data);
            handler.sendMessage(msg);
        }
    };
    new Thread(runnable).start();  //启动子线程
    方法二:强制在UI线程更新UI请求网络

    setContentView(R.layout.activity_main);
    if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }

    源码下载欢迎Star(updating):https://github.com/JinBoy23520/CoderToDeveloperByTCLer




    展开全文
  • 使用基于TCP 协议的双向通信时,网络中的两个应用程序之间必须首先建立一个连接,这两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。 建立网络通信连接至少要一对端口号(socket)。...
  • IO多路复用服务器编程
  • java实现线程通信的几种方式

    万次阅读 2020-05-30 19:34:35
    在多线程的世界里,线程与线程之间的交互无处不在,只不过在平时的开发过程中,大多数情况下,我们都在单线程的模式下进行编码,即使有,也直接借助框架自身的机制实现了,其实线程之间的通信在JDK中是一个比较深的...
  • Redis单线程模型

    千次阅读 2019-09-18 21:58:16
    1.Redis单线程模型 1.1.文件事件处理器 1>.Redis基于Reactor模式开发了网络事件处理器,这个处理器就叫做文件事件处理器(file event handler).这个文件事件处理器是单线程的,所以Redis才叫做单线程的模型,文件事件...
  • Java单线程与多线程

    千次阅读 2019-03-08 18:17:52
    在我们了解单线程和多线程之前,我们必须搞清楚什么是进程。 一个运行起来的程序就是一个进程! 那程序又是什么呢? 对程序的通俗定义就是:一段可执行的代码。 当我们执行一段Java程序时,就在java虚拟机(JVM)中...
  • 为什么说Redis是单线程的以及Redis为什么这么快!

    万次阅读 多人点赞 2018-03-07 17:39:56
    既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)。 可以参考: https://redis.io/topics/faq 看到这里,你可能会气哭!本以为会有什么重大的技术...
  • 进程间通信线程通信

    千次阅读 2020-08-18 20:26:22
    线程通信 进程和线程的区别 程序只是一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体。而进程则不同,它是程序在某个数据集上的执行。进程是一个动态的实体,它有自己的生命周期。它因...
  • 多线程之线程通信

    万次阅读 2018-02-28 15:56:33
    http://blog.csdn.net/jiazhen/article/details/1611721简介 线程之间通信的两个基本问题是互斥和同步。 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程...
  • Redis 单线程还是多线程?

    千次阅读 2019-09-18 09:51:27
    Redis 单线程还是多线程 前段时间无意间看到一篇博客,讲述了Redis6即将在年底发布的事情,好奇心驱动下搜索了官网,想看看新版Redis带来了什么新的功能,果然得到证实Redis在年底将发布新的版本:6.0,并且Redis...
  • 摘 要: 提出了一种在Windows NT下基于TCP/IP协议的多线程通信的设计与实现方法,在此基础上给出了多线程通信在蓄电池远程监控系统中的应用实例。 关键词: 多线程 实时性 TCP/IP协议 远程监控系统  传统的应用...
  • 11_C++多线程线程通信

    千次阅读 2019-08-08 18:06:56
    参考: https://m.imooc.com/article/289630 C++11 标准库新引入的线程库 ...(一)多线程编程 #include <iostream> #include <thread> #include <mutex> #include <condi...
  • Python 多线程线程通信

    千次阅读 2020-09-05 17:27:00
    一个线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每个线程并行执行不同的任务。 由于线程是操作系统直接支持的执行单元,因此,高级语言(如 Python、Java 等)通常都内置多线程的支持。...
  • Redis到底是单线程还是多线程?

    千次阅读 2020-05-18 15:28:54
    Redis采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。这个数据不比采用单进程多线程的同样基于内存的 KV 数据库 Memcached 差!...
  • java线程通信的三种方式

    千次阅读 2019-04-02 14:26:08
    1、传统的线程通信。 在synchronized修饰的同步方法或者修饰的同步代码块中使用Object类提供的wait(),notify()和notifyAll()3个方法进行线程通信。 关于这3个方法的解释: wait():导致当前线程等待,直到其他线程...
  • 单线程与多线程的区别

    万次阅读 多人点赞 2017-11-27 11:03:18
    什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。...线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区
  • 1、首先redis是单线程的,为什么redis会是单线程的呢? 从redis的性能上进行考虑,单线程避免了上下文频繁切换问题,效率高; 从redis的内部结构原理进行考虑,redis是基于Reactor模式开发了自己的网络事件处理器:...
  • 进程间通信线程通信总结

    万次阅读 2019-02-16 16:06:57
    写在前面 面试的时候一定不要疲劳战,比如上午面了一个,然后中午不休息直接赶到另外一个...进程间通信又称IPC(Inter-Process Communication),指多个进程之间相互通信,交换信息的方法。根据进程通信时信息量大小的...
  • 单线程JavaScript实现多线程并发的功能,语意上参考Java实现,提供getState / sleep / join等API,并提供线程间通信的功能,依赖ES6语法,基于Promise和Async函数实现,故需要Babel编译才能运行。JavaScrpt本来...
  • 单线程Redis 和 I/O 多路复用

    千次阅读 2019-05-23 09:56:42
    redis 核心就是 如果我的数据全都在内存里,我单线程的去操作 就是效率最高的,为什么呢,因为多线程的本质就是 CPU 模拟出来多个线程的情况,这种模拟出来的情况就有一个代价,就是上下文的切换,对于一个内存的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 267,975
精华内容 107,190
关键字:

单线程通信