java 线程 获取消息_获取java线程中信息

怎样获取java线程中信息?

在进行多线程编程中,比较重要也是比较困难的一个操作就是如何获取线程中的信息。大多数人会采取比较常见的一种方法就是将线程中要返回的结果存储在一个字段中,然后再提供一个获取方法将这个字段的内容返回给该方法的调用者。如以下的ReturnThreadInfo类:

package threadtest1; /** * * @author shi mingxiang */ public class ReturnThreadInfo extends Thread {   private String str;   public ReturnThreadInfo() {     this.str = "Hello";   }   public void run(){       this.str = "Hello World!";   }   public String getThreadInfo(){     return this.str;   } }

大家可以看到该类是一个线程类并含有一个初始值为"Hello"的字段str以及一个可以返回str值的方法:getThreadInfo(),而且当这个线程启动后str会被赋于新值:"Hello World!"。现在我想在另外一个类中启动ReturnThreadInfo线程,并通过getThreadInfo()方法获取值为"Hello World!"的变量并打印输出到控制台中。以下给出一个实现该功能的Main类:

package threadtest1; /** * * @author shi mingxiang */ public class Main{   public Main() {   }   /**    * @param args the command line arguments    */   public static void main(String[] args) {     ReturnThreadInfo returnThreadInfo = new ReturnThreadInfo();     returnThreadInfo.start(); //创建并启动ReturnThreadInfo线程     System.out.println(returnThreadInfo.getThreadInfo()); //获取并输出returnThreadInfo对象的str的值     } }

以上是一个多数熟悉单线程编程的人在第一反应下给出的实现方法。但是该类在运行的时候输出的结果却不是期望的"Hello World!"而是"Hello",这是由于线程的竞争条件导致的(由于ReturnThreadInfo线程和Main线程的优先级都为5,所以在很大几率上ReturnThreadInfo线程的run()方法还没有运行,Main类就已经运行System.out.println(returnThreadInfo.getThreadInfo());将"Hello"输出了。具体的原理可以参见另一篇文章:"java多线程的几点误区")。有的人可能会立即想到把ReturnThreadInfo线程的优先级设高些(比如最大的10)就可以returnThreadInfo线程的run()方法先运行完,然后Main类的System.out.println(returnThreadInfo.getThreadInfo())再运行,这样输出的结就一定是期望的"Hello World!"了。这种通过调整线程优先级的方法固然可以在某种程度上解决该问题,但是线程争用CPU运行时间的原理却决不仅仅只是优先级高低的原因(优先级高的线程并不意味着一定比优先级低的线程先运行,只是几率要更大一些)。你并不希望ReturnThreadInfo线程9999次都比Main先运行,却在最关键的一次在Main之后再运行。因此下面给出两种比较常见的获取线程信息的方法:

一、轮询

比较常见的一种解决方案是,让线程类获取方法在结果字段设置之前返回一个标志值。然后主线程定时询问获取方法,看是否返回了标志之外的值。以下给出了具体的实现方法,该方法不断测试str的值是否为"Hello",如果不为"Hello"才打印输出它。例如:

package threadtest1; /** * * @author shi mingxiang */ public class Main{   public Main() {   }   /**    * @param args the command line arguments    */   public static void main(String[] args) {     ReturnThreadInfo returnThreadInfo = new ReturnThreadInfo();     returnThreadInfo.start(); //创建并启动ReturnThreadInfo线程       while(true){       String str = returnThreadInfo.getThreadInfo();       if(!str.equals("Hello")){          System.out.println(returnThreadInfo.getThreadInfo());          break;       }     }     } }

这种方案虽然能起到作用,但是它做了大量不需要做的工作。事实上,还有一种更简单有效的方法来解决这个问题。

二、回调

轮询方法最大的特点是主类Main不断询问线程类是否结束,这实际上大量浪费了运行时间,特别是当线程特别多的时候。因此如果反过来在线程结束时,由线程自己告诉主类Main线程已经结束,然后Main再获取并输出str的值,这样就避免了轮询方法所带来的不必要的系统开销问题。

在具体的实现过程中,线程可以在结束时通过调用主类中的一个方法来实现告知功能,这种方法叫做回调。这样主类Main就可以在等待线程结束时休息,也就不会占用运行线程的时间。下面是修改后的Main类:

public class Main{   public Main() {   }   /**    * @param args the command line arguments    */   public static void main(String[] args) {     // TODO code application logic here     ReturnThreadInfo returnThreadInfo = new ReturnThreadInfo();     returnThreadInfo.start();   }   public static void receiveStr(String str){     System.out.println(str);   } }

相比于前面,我们在Main类中添加了一个静态方法receiveStr(String str),该方法是供线程结束之前调用,通过参数str将要返回的线程信息返回给Main类并输出显示出来。下面是修改后的ReturnThreadInfo类,该类在线程结束前回调了Main.receiveStr方法,通知线程已结束。

package threadtest1; /** * * @author shi mingxiang */ public class ReturnThreadInfo extends Thread {   private String str;   public ReturnThreadInfo() {     this.str = "Hello";   }   public void run(){       this.str = "Hello World!";    Main.receiveStr(str); //回调receiveStr方法   } }

如果有很多个对象关心线程的返回的信息,线程可以保存一个回调对象列表。某个对象可以通过已经定义的一个对象将自己添加到列表中,表示自己对这些信息的关注。如果有多个类的实例关心这些信息,也可以定义一个interface,在interface中声名回调方法,然后这些类都实现这个接口。其实这是典型的java处理事件的方法,这么做可以使得回调更灵活,可以处理涉及更多线程、对象和类的情况。稍后会给出这种模仿事件处理模型的回调的实现方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/295409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OAuth 2.0 扩展协议之 PKCE

前言阅读本文前需要了解 OAuth 2.0 授权协议的相关内容, 可以参考我的上一篇文章 OAuth 2.0 的探险之旅[1]。PKCE 全称是 Proof Key for Code Exchange, 在2015年发布, 它是 OAuth 2.0 核心的一个扩展协议, 所以可以和现有的授权模…

欧洲杯直播助PPTV日均流量登顶视频行业首位

随着意大利溃败,西班牙最终捧杯,四年一度火爆的欧洲杯赛事也就此落下帷幕。令人欣喜的是,在本届欧洲杯比赛的直播过程中,由于比赛安排再深夜,互联网应用取代传统电视台成为人们观看赛事的主要渠道,各大视频…

深度优先算法

/*** @author Think* 给定整数a1,a2,a3,a4…,判断是否可以从中选出若干数,使他们的和恰好为K*/ public class 深度优先算法 {//n=4,a={1,2,4,7};k=13;public static int n=4;public static int [] a={1,2,4,7};public static int k=13;public static void main(String[] ar…

/etc/network/interfaces

man resolvconf man interfaceshttp://linux-net.osdl.org/index.php/Bridge示例:# This file describes the network interfaces available on your system# and how to activate them. For more information, see interfaces(5).# The loopback network interfaceauto lo ifa…

nashorn js 调用 java_从nashorn(JDK 8 JavaScript引擎)调用char []输入参数调用Java函数?...

我想从Oracle的nashorn JavaScript引擎中调用一个带有 char[] 输入参数的Java函数(非数组参数类型的函数对我来说没问题) .如果我用JavaScript字符串文字调用Java函数,nashorn balksjavax.script.ScriptException: TypeError: Can not invoke method[jdk.internal.d…

Netty之有效规避内存泄漏

有过痛苦的经历,特别能写出深刻的文章 —— 凯尔文. 肖 直接内存是IO框架的绝配,但直接内存的分配销毁不易,所以使用内存池能大幅提高性能,也告别了频繁的GC。但,要重新培养被Java的自动垃圾回收惯坏了的惰性。 Netty有…

.NET 6新特性试用 | record struct

前言在以前的文章中,我们介绍过record类型,它具有不变性(《为什么应该用record来定义DTO》)和值相等性(《为什么应该用record来定义DTO(续)》)。record是引用类型。而在.NET 6中,我们可以使用record struct定义值类型。…

原来我们看到的世界地图竟这样震撼!多年的地理白学了...

▲ 点击查看几乎每个家庭都会有两张地图:一张世界地图,一张中国地图。薄薄的两张纸,蕴藏着让每个人学会“看世界”的磅礴力量。哈佛上一任校长,也是300多年来唯一一位女校长德鲁吉尔平福斯特(Drew Gilpin Faust&#x…

Exchange Powershell查看用户最后登陆邮箱时间

在Exchange日常管理中,我们可能经常会遇到这样的问题,就是怎么来知道一个用户最后的登录时间?这个问题在使用Exchange powershell就能很好的解决了。 用管理员身份运行Exchange management powershell 查看某一个邮箱数据库的统计信息&#x…

在n个火柴里面拿3根出来拼接成最大三角形的周长

求三角形max周长 public class 求三角形max周长 { public static void main(String[] args) {/*** 有n个棍子 每个棍子的长度是a[i]* 3<n<100;* 1<a[i]<100; */ System.out.println("请输入n根绳子"); Scanner input new Scanner(System.in); int ni…

mysql之mysqldump命令

导出要用到MySQL的mysqldump工具&#xff0c;基本用法是&#xff1a; shell> mysqldump [OPTIONS] database [tables] 如果你不给定任何表&#xff0c;整个数据库将被导出。 通过执行mysqldump --help&#xff0c;你能得到你mysqldump的版本支持的选项表。 注意&#xff0c;…

易企秀制作的步骤

2019独角兽企业重金招聘Python工程师标准>>> 1、选图很关键 &#xff08;图片干净 整洁&#xff0c;不同方位展示 &#xff0c;符合主题&#xff09;。 2、配上说明性文字 简明扼要 3、选择合适的模板和背景音乐。 4、及时沟通与调整。 转载于:https://my.oschina.n…

java instanceof运算符_Java instanceof 运算符的使用方法

用法&#xff1a;(类型变量 instanceof 类|接口)作用&#xff1a;instanceof 操作符用于判断前面的对象是否是后面的类&#xff0c;或者其子类、实现类的实例。如果是则返回true 否则就返回false。注意&#xff1a; instanceof前面的操作数的编译时类型要么与后面的类相同&…

C# WPF MVVM模式Prism框架下事件发布与订阅

01—前言处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信&#xff0c;Prism提供了一种事件机制&#xff0c;可以在应用程序中低耦合的模块之间进行通信&#xff0c;该机制基于事件聚合器服务&#xff0c;允许发布者和订阅者之间通过事件进行通讯&#xff0c;且彼此之…

这几部高分学科纪录片,助力孩子涨姿势拓视野~

全世界只有3.14 % 的人关注了爆炸吧知识▌导读本文为同学们整理了几部高分经典学科纪录片&#xff0c;对应文学、数学、经济学、地理、化学。这不仅是课堂学习的补充与延伸&#xff0c;更是开拓视野、激发学习内驱力的绝佳利器。建议收藏&#xff01;&#xff08;关注视频号少年…

Linux 学习_在Linux下面安装tomcat

要在linux下面安装tomcat&#xff0c;首先我们需要做一些准备工作.... 下载tomcat&#xff1a; 下载地址&#xff1a;http://tomcat.apache.org/download-60.cgi 下载&#xff1a;tar.gz 如图&#xff1a; 说明&#xff1a; WinISO安装版&#xff1a;下载地址&#xff1a;http…

Codeforces 474C Captain Marmot 给定4个点和各自旋转中心 问旋转成正方形的次数

题目链接&#xff1a;点击打开链接 题意&#xff1a; 给定T表示case数 以下4行是一个case 每行2个点&#xff0c;u v 每次u能够绕着v逆时针转90 问最少操作多少次使得4个u构成一个正方形。 思路&#xff1a; 枚举判可行 #include <iostream> #include <cmath> #inc…

穷竭搜索

/**穷竭搜索是将所有的可能性罗列出来&#xff0c;在其中找到答案的方法&#xff0c;这里我们主要介绍深度优先搜索和广度优先搜索* author Think**/ public class 穷竭搜索 {public static void main(String[] args) {}//计算阶层 n&#xff01;n*(n-1)&#xff01;public sta…

JQUERY插件学习之jQuery UI

jQuery UI:http://jqueryui.com/ jQuery UI介绍: jQuery UI 是以 jQuery 为基础的开源 JavaScript 网页用户界面代码库。包含底层用户交互、动画、特效和可更换主题的可视控件。我们可以直接用它来构建具有很好交互性的web应用程序。所有插件测试能兼容 IE 6.0, Firefox 3, Saf…

java 数组拼接字符串_如何在java里java字符串数组合并成一个数组?

展开全部java里java字符串数组合并成一个数组方法如下&#xff1a;//方法一 Arrays类String[] a {"A","B","C"};String[] b {"D","E"};// List list Arrays.asList(a); --OK// List list Arrays.asList("A",…