进程线程调度的主要功能有 线程间通信的几种方法

一.导言
本文总结了我对JAVA多线程中线程间通信的理解,主要通过代码和文本相结合的方式来讨论线程间的通信,所以我从书中摘录了一些样例代码 。

进程线程调度的主要功能有 线程间通信的几种方法

文章插图
文章插图

第二,线程之间的通信方式
①同步
这里的同步意味着多个线程通过synchronized关键字相互通信 。
参考示例:
公共类my object { synchronized public void method a(){//做点什么….} synchronized public void method b(){//do some other thing } } public class ThreadA扩展Thread { private MyObject object//省略构造函数@ override public void run(){ super . run();object . methoda();} }公共类ThreadB扩展Thread { private MyObject object//省略构造函数@ override public void run(){ super . run();object . methodb();} }公共类Run { public static void main(String[]args){ my object object = new my object();//线程A和线程B持有同一个对象:object threada = new threada(object);ThreadB b = new ThreadB(object);a . start();b . start();}}}因为线程A和线程B持有同一个MyObject类的object对象,虽然这两个线程需要调用不同的方法,但是它们是同步执行的 。例如,线程B需要等待线程A执行完methodA()方法,然后才能执行methodB()方法 。这样线程A和线程B就实现了通信 。
这种方式,本质上就是“共享记忆”交流 。多个线程需要访问同一个共享变量,谁得到锁(访问权)谁就可以执行 。
②轮询方式时
代码如下:
【进程线程调度的主要功能有 线程间通信的几种方法】导入Java . util . ArrayList;导入Java . util . list;公共类MyList { private List & lt字符串& gtlist = new ArrayList & lt字符串& gt();public void add(){ list . add(” elements “);} public int size(){ return list . size();} }导入我的列表 。MyList公共类ThreadA扩展了Thread { private MyList listpublic ThreadA(my list list){ super();this.list = list} @覆盖public void run(){ try { for(int I = 0;我& lt10;i++){ list . add();system . out . println(” added “+(I+1)+” elements “);thread . sleep(1000);} } catch(interrupted exception e){ e . printstacktrace();} } }导入我的列表 。MyList公共类ThreadB扩展了Thread { private MyList listpublic ThreadB(my list list){ super();this.list = list} @ override public void run(){ try { while(true){ if(list . size()= = 5){ system . out . println(” = = 5,线程B准备退出”);抛出new interrupted exception();} } } catch(interrupted exception e){ e . printstacktrace();} } }导入我的列表 。MyList导入extthread 。ThreadA导入extthread 。ThreadBpublic class Test { public static void main(String[]args){ my list service = new my list();ThreadA a = new ThreadA(服务);A . setname(” A “);a . start();ThreadB b = new ThreadB(服务);B . set name(” B “);b . start();}}这样,线程A不断改变条件,线程ThreadB通过while语句不断检查这个条件(list.size()==5)是否为真,从而实现线程间的通信 。但是这种方式会浪费CPU资源 。之所以浪费资源,是因为JVM调度器把CPU交给线程B执行的时候,并没有做任何“有用”的工作,而是在不断测试某个条件是否成立 。就像现实生活中,有人一直看着手机屏幕,看有没有来电,而不是:做别的 。有电话时,按铃通知TA电话来了 。
关于线程轮询的影响,请参考:
http://www.cnblogs.com/hapjin/p/5467984.html
这种方法还有另一个问题:
有关轮询条件的可见性,请参考:
http://www.cnblogs.com/hapjin/p/5492880.html
线程首先将变量读入局部线程栈空中,然后修改局部变量 。因此,如果线程B每次都采用局部条件变量,即使另一个线程更改了轮询条件,它也不会注意到,这也会导致无限循环 。