java学习--线程间通信

本文详细介绍了线程间的通信机制,包括同步、等待唤醒、生产者消费者模型等内容,并讲解了如何通过优化代码来提高线程间通信的效率。此外,还介绍了线程的管理技巧,如停止线程、守护线程、线程优先级等。

知识点


01)线程间通信——示例代码



  1. public class InputOutputThread {  
  2.     public static void main(String[] args) {  
  3.         Res r = new Res();//资源  
  4.         Input in = new Input(r);  
  5.         Output out = new Output(r);  
  6.         Thread t1 = new Thread(in);  
  7.         Thread t2 = new Thread(out);  
  8.         t1.start();  
  9.         t2.start();  
  10.     }  
  11. }  
  12. class Res{  
  13.     String name;  
  14.     String an;  
  15. }  
  16. class Input implements Runnable{  
  17.     private Res r;  
  18.     Input(Res r){  
  19.         this.r = r;  
  20.     }  
  21.     public void run(){  
  22.         int x = 0;  
  23.         while(true){  
  24.             if (x == 0){  
  25.                 r.name = "汤姆";  
  26.                 r.an = "猫咪";  
  27.             }else{  
  28.                 r.name = "杰瑞";  
  29.                 r.an = "老鼠";  
  30.             }  
  31.             x = (x + 1) % 2;  
  32.         }  
  33.     }  
  34. }  
  35. class Output implements Runnable{  
  36.     private Res r;  
  37.     Output(Res r){  
  38.         this.r = r;  
  39.     }  
  40.     public void run(){    
  41.         while(true)  
  42.             System.out.println(r.name + "是: " + r.an);  
  43.     }  
  44. }//陷入死循环中~  

02)解决安全问题。

  1. public class InputOutputThread_2 {  
  2.     public static void main(String[] args) {  
  3.         Res_2 r = new Res_2();//资源  
  4.         Input_2 in = new Input_2(r);  
  5.         Output_2 out = new Output_2(r);  
  6.         Thread t1 = new Thread(in);  
  7.         Thread t2 = new Thread(out);  
  8.         t1.start();  
  9.         t2.start();  
  10.     }  
  11. }  
  12. class Res_2{  
  13.     String name;  
  14.     String an;  
  15. }  
  16. class Input_2 implements Runnable{  
  17.     private Res_2 r;  
  18.     Input_2(Res_2 r){  
  19.         this.r = r;  
  20.     }  
  21.     public void run(){  
  22.         int x = 0;  
  23.         while(true){  
  24.             synchronized(r){//同一个锁。  
  25.                 if (x == 0){  
  26.                     r.name = "汤姆";  
  27.                     r.an = ".猫.咪.";  
  28.                 }else{  
  29.                     r.name = "杰瑞";  
  30.                     r.an = "老...鼠";  
  31.                 }  
  32.                 x = (x + 1) % 2;  
  33.             }  
  34.         }  
  35.     }  
  36. }  
  37. class Output_2 implements Runnable{  
  38.     private Res_2 r;  
  39.     Output_2(Res_2 r){  
  40.         this.r = r;  
  41.     }  
  42.     public void run(){    
  43.         while(true)  
  44.             synchronized(r){//同一个锁。  
  45.                 System.out.println(r.name + "是: " + r.an);  
  46.             }  
  47.     }  
  48. }  

03)等待唤醒机制

  1. /* 
  2.  * 等待唤醒机制。 
  3.  *  
  4.  * wait(); 
  5.  * notify(); 
  6.  * notifyAll(); 
  7.  * 都使用在同步中,因为要对持有监视器(锁)的线程进行操作。 
  8.  * 所以要使用在同步中,因为只有同步才具有锁。 
  9.  *  
  10.  * 为什么这些操作线程的方法要定义在Object类中呢? 
  11.  * 因为这些方法在操作同步中线程时,都必须要标识它们所操作线程所持有的锁。 
  12.  * 只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒,不可以对不同锁上的notify唤醒。 
  13.  * 也就是等待和唤醒必须是在同一个锁内。 
  14.  * 而锁可以是任意对象,所以可以被任意对象调用的方法就定义在Object类中。 
  15.  */  
  16. public class InputOutputThread_3 {  
  17.     public static void main(String[] args) {  
  18.         Res_3 r = new Res_3();//资源  
  19.         Input_3 in = new Input_3(r);  
  20.         Output_3 out = new Output_3(r);  
  21.         Thread t1 = new Thread(in);  
  22.         Thread t2 = new Thread(out);  
  23.         t1.start();  
  24.         t2.start();  
  25.     }  
  26. }  
  27. class Res_3{  
  28.     String name;  
  29.     String an;  
  30.     boolean flag = false;  
  31. }  
  32. class Input_3 implements Runnable{  
  33.     private Res_3 r;  
  34.     Input_3(Res_3 r){  
  35.         this.r = r;  
  36.     }  
  37.     public void run(){  
  38.         int x = 0;  
  39.         while(true){  
  40.             synchronized(r){//同一个锁。  
  41.                 if (r.flag)//如果为真,等待。  
  42.                     try{r.wait();}catch(Exception e){}  
  43.                 if (x == 0){  
  44.                     r.name = "汤姆";  
  45.                     r.an = ".猫.咪.";  
  46.                 }else{  
  47.                     r.name = "杰瑞";  
  48.                     r.an = "老...鼠";  
  49.                 }  
  50.                 x = (x + 1) % 2;  
  51.                 r.flag = true;//将flag设置为真。  
  52.                 r.notify();//唤醒另外一个线程。  
  53.             }  
  54.         }  
  55.     }  
  56. }  
  57. class Output_3 implements Runnable{  
  58.     private Res_3 r;  
  59.     Output_3(Res_3 r){  
  60.         this.r = r;  
  61.     }  
  62.     public void run(){    
  63.         while(true){  
  64.             synchronized(r){//同一个锁。  
  65.                 if (!r.flag)//如果为假,等待。  
  66.                     try{r.wait();}catch(Exception e){}  
  67.                 System.out.println(r.name + "是: " + r.an);  
  68.                 r.flag = false;//将falg设置为false。  
  69.                 r.notify();//唤醒另外一个线程。  
  70.             }  
  71.         }  
  72.     }  
  73. }  

04)代码优化

  1. /* 
  2.  * 代码的优化。 
  3.  */  
  4. public class InputOutputYouHua {  
  5.     public static void main(String[] args) {  
  6.         ResY r = new ResY();//资源  
  7.         new Thread(new InputY(r)).start();  
  8.         new Thread(new OutputY(r)).start();  
  9.     }  
  10. }  
  11. class ResY{  
  12.     String name;  
  13.     String an;  
  14.     boolean flag = false;  
  15.     public synchronized void set(String name, String an){  
  16.         if (flag)  
  17.             try{this.wait();}catch(Exception e){}  
  18.         this.name = name;  
  19.         this.an = an;  
  20.         this.flag = true;//将flag设置为真。  
  21.         this.notify();//唤醒另外一个线程。  
  22.     }  
  23.     public synchronized void out(){  
  24.         if (!flag)  
  25.             try{this.wait();}catch(Exception e){}  
  26.         System.out.println(name + "是: " + an);  
  27.         this.flag = false;//将flag设置为真。  
  28.         this.notify();//唤醒另外一个线程。  
  29.     }  
  30. }  
  31. class InputY implements Runnable{  
  32.     private ResY r;  
  33.     InputY(ResY r){  
  34.         this.r = r;  
  35.     }  
  36.     public void run(){  
  37.         int x = 0;  
  38.         while(true){  
  39.                 if (x == 0)  
  40.                     r.set("汤姆"".猫.咪.");  
  41.                 else  
  42.                     r.set("杰瑞""老...鼠");  
  43.                 x = (x + 1) % 2;  
  44.         }  
  45.     }  
  46. }  
  47. class OutputY implements Runnable{  
  48.     private ResY r;  
  49.     OutputY(ResY r){  
  50.         this.r = r;  
  51.     }  
  52.     public void run(){    
  53.         while(true)  
  54.             r.out();  
  55.     }  
  56. }  

05)线程中通信——生产者消费

  1. /* 
  2.  * 对于多个生产者和消费者。 
  3.  * 为什么要定义while判断标记。 
  4.  * 原因:需要让被唤醒的线程再一次判断标记。 
  5.  *  
  6.  * 为什么定义notifyAll(); 
  7.  * 因为需要唤醒对方的线程。 
  8.  * 因为只有notify()的话,容易只唤醒本方线程的情况。导致程序中的所有线程都等待。 
  9.  */  
  10. public class PrdCemDemo {  
  11.     public static void main(String[] args) {  
  12.         Resource r = new Resource();//共享资源  
  13.         new Thread(new Producer(r)).start();//生产线程0  
  14.         new Thread(new Producer(r)).start();//生产线程1  
  15.         new Thread(new Consumer(r)).start();//消费线程2  
  16.         new Thread(new Consumer(r)).start();//消费线程3  
  17.     }  
  18. }  
  19. class Resource{  
  20.     private String name;  
  21.     private int count = 1;  
  22.     private boolean flag = false;  
  23.       
  24.     public synchronized void set(String name){//生产商品  
  25.         while (flag)  
  26.             try{  
  27.                 this.wait();  
  28.             }catch(Exception e){  
  29.                   
  30.             }  
  31.         this.name = name + "----" + count++;  
  32.           
  33.         System.out.println(Thread.currentThread().getName() + "...生产者" + this.name);  
  34.         flag = true;  
  35.         this.notifyAll();  
  36.     }  
  37.     public synchronized void out(){//出售商品  
  38.         while (!flag)  
  39.             try{  
  40.                 this.wait();  
  41.             }catch(Exception e){  
  42.                   
  43.             }  
  44.         System.out.println(Thread.currentThread().getName() + "...消费者..." + this.name);  
  45.         flag = false;  
  46.         this.notifyAll();  
  47.     }  
  48. }  
  49.   
  50. class Producer implements Runnable{  
  51.     private Resource r;  
  52.     Producer(Resource r){  
  53.         this.r = r;  
  54.     }  
  55.     public void run(){  
  56.         while(true){  
  57.             r.set("+商品+");  
  58.         }  
  59.     }  
  60. }  
  61. class Consumer implements Runnable{  
  62.     private Resource r;  
  63.     Consumer(Resource r){  
  64.         this.r = r;  
  65.     }  
  66.     public void run(){  
  67.         while(true){  
  68.             r.out();  
  69.         }  
  70.     }  
  71. }  
运行结果如下图所示:


06)生产消费者升级版(JDK1.5版本开始之后)

  1. /* 
  2.  * 从JDK1.5版本开始,提供了多线程的解决方案。 
  3.  * 将同步synchronzied替换成现有的Lock方案。 
  4.  * 将Object中的wait、notify、notifyAll,替换成了Condition对象。 
  5.  * 该对象可以Lock锁,进行获取。 
  6.  */  
  7. public class PrdCemSuperDemo {  
  8.     public static void main(String[] args) {  
  9.         ResourceSup r = new ResourceSup();//共享资源  
  10.         new Thread(new ProducerSup(r)).start();//生产线程0  
  11.         new Thread(new ProducerSup(r)).start();//生产线程1  
  12.         new Thread(new ConsumerSup(r)).start();//消费线程2  
  13.         new Thread(new ConsumerSup(r)).start();//消费线程3  
  14.     }  
  15. }  
  16. class ResourceSup{  
  17.     private String name;  
  18.     private int count = 1;  
  19.     private boolean flag = false;  
  20.     private Lock lock = new ReentrantLock();  
  21.     private Condition con_c = lock.newCondition();//生产者标记  
  22.     private Condition con_p = lock.newCondition();//消费者标记  
  23.     public void set(String name) throws InterruptedException{//生产商品  
  24.         lock.lock();//获取锁。  
  25.         try{  
  26.             while (flag)  
  27.                 con_c.await();//生产者线程等待。  
  28.             this.name = name + "----" + count++;  
  29.             System.out.println(Thread.currentThread().getName() + "...生产者" + this.name);  
  30.             flag = true;  
  31.             con_p.signal();//唤醒消费者线程。  
  32.         }finally{  
  33.             lock.unlock();//释放锁  
  34.         }  
  35.     }  
  36.     public void out() throws InterruptedException{//出售商品  
  37.         lock.lock();//获取锁  
  38.             try{  
  39.                 while (!flag)  
  40.                     con_p.await();//消费者线程等待。  
  41.                 System.out.println(Thread.currentThread().getName() + "...消费者..." + this.name);  
  42.                 flag = false;  
  43.                 con_c.signal();//唤醒生产者线程。  
  44.             }finally{  
  45.                 lock.unlock();//释放锁。  
  46.             }  
  47.     }  
  48. }  
  49.   
  50. class ProducerSup implements Runnable{  
  51.     private ResourceSup r;  
  52.     ProducerSup(ResourceSup r){  
  53.         this.r = r;  
  54.     }  
  55.     public void run(){  
  56.         while(true){  
  57.             try{  
  58.                 r.set("+商品+");  
  59.             }catch(InterruptedException e){  
  60.                   
  61.             }  
  62.         }  
  63.     }  
  64. }  
  65. class ConsumerSup implements Runnable{  
  66.     private ResourceSup r;  
  67.     ConsumerSup(ResourceSup r){  
  68.         this.r = r;  
  69.     }  
  70.     public void run(){  
  71.         while(true){  
  72.             try{  
  73.                 r.out();  
  74.             }catch(InterruptedException e){  
  75.                   
  76.             }  
  77.         }  
  78.     }  
  79. }  


07)停止线程

  1. /* 
  2.  * stop方法以及过时。 
  3.  * 如果停止线程? 
  4.  * 只有一种方法,run方法结束。 
  5.  * 开启多线程运行,运行代码通常都是循环结构的,只要控制住循环,就可以让run方法结束,也就是线程结束。 
  6.  *  
  7.  * 特殊情况:当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。 
  8.  *  
  9.  * 当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结状态进行清除。 
  10.  * 强制让线程恢复到运行状态,这样就可以操作标记让线程结束。 
  11.  * Thread提供了该方法:interrupt() 
  12.  */  
  13. public class StopThreadDemo {  
  14.     public static void main(String[] args) {  
  15.         StopThread st = new StopThread();  
  16.         Thread t1 = new Thread(st);  
  17.         Thread t2 = new Thread(st);  
  18.           
  19.         int num = 0;  
  20.         while(true){  
  21.             if(num++ == 60){  
  22. //              st.ChangeFlag();  
  23.                 t1.interrupt();//强制清除状态。  
  24.                 t2.interrupt();  
  25.                 break;  
  26.             }  
  27.             System.out.println(Thread.currentThread().getName() + "...." + num);  
  28.         }  
  29.           
  30.     }  
  31. }  
  32.   
  33. class StopThread implements Runnable{  
  34.     private boolean flag = true;  
  35.     public synchronized void run(){  
  36.         while(flag){  
  37.             try{  
  38.                 wait();  
  39.             }catch(InterruptedException e){  
  40.                 System.out.println(Thread.currentThread().getName() + " ... InterruptedException");  
  41.                 flag = false;  
  42.             }  
  43.             System.out.println(Thread.currentThread().getName() + " ... run");  
  44.         }  
  45.     }  
  46. //  public void ChangeFlag(){  
  47. //      flag = false;  
  48. //  }  
  49. }  

08)守护线程

  1. /* 
  2.  * 设置守护线程:setDaemon(true);也就是后台线程。 
  3.  * 注意:必须在开启线程之前设置。 
  4.  */  
  5. public class SetDaemonThreadDemo {  
  6.     public static void main(String[] args) {  
  7.         SetDaemonThread st = new SetDaemonThread();  
  8.         Thread t1 = new Thread(st);  
  9.         Thread t2 = new Thread(st);  
  10.           
  11.         t1.setDaemon(true);//设置为守护线程,也就是后台线程。  
  12.         t2.setDaemon(true);//注意:必须在开启线程之前设置。  
  13.         t1.start();  
  14.         t2.start();  
  15.           
  16.         int num = 0;  
  17.         while(true){  
  18.             if(num++ == 60){  
  19. //              t1.interrupt();//强制清除状态。  
  20. //              t2.interrupt();  
  21.                 break;  
  22.             }  
  23.             System.out.println(Thread.currentThread().getName() + "...." + num);  
  24.         }  
  25.     }  
  26. }  
  27.   
  28. class SetDaemonThread implements Runnable{  
  29.     private boolean flag = true;  
  30.     public void run(){  
  31.         while(flag){  
  32.             System.out.println(Thread.currentThread().getName() + " ... run");  
  33.         }  
  34.     }  
  35. }  

09)join方法

  1. /* 
  2.  * Join: 
  3.  * 当t2线程执行到了t1线程的.join方法时,t2就会等待,等t1线程执行完,t2才会执行。 
  4.  * join用来临时加入线程执行。 
  5.  */  
  6. public class JoinThreadDemo {  
  7.     public static void main(String[] args) throws InterruptedException{  
  8.         JoinThread jt = new JoinThread();  
  9.         Thread t1 = new Thread(jt);  
  10.         Thread t2 = new Thread(jt);  
  11.         t1.start();  
  12.         t1.join();//t1申请cup执行权。主线程main放弃执行权,变更为冻结状态。  
  13.         t2.start();  
  14.         for(int i = 0; i < 80; i++){  
  15.             System.out.println("Main..." + i);  
  16.         }  
  17.     }  
  18. }  
  19. class JoinThread implements Runnable{  
  20.     public void run(){  
  21.         for(int i = 0; i < 70; i++){  
  22.             System.out.println(Thread.currentThread().getName() + "..." + i);  
  23.         }  
  24.     }  
  25. }  

10) 优先级

  1. public class ToStringThreadDemo {  
  2.     public static void main(String[] args) throws InterruptedException{  
  3.         ToStringThread jt = new ToStringThread();  
  4.         Thread t1 = new Thread(jt);  
  5.         Thread t2 = new Thread(jt);  
  6.         t1.start();  
  7. //      t1.setPriority(Thread.MAX_PRIORITY);//设置优先级  
  8.         t2.start();  
  9.         for(int i = 0; i < 80; i++){  
  10.             System.out.println(Thread.currentThread().toString() + "Main..." + i);  
  11.         }  
  12.     }  
  13. }  
  14. class ToStringThread implements Runnable{  
  15.     public void run(){  
  16.         for(int i = 0; i < 70; i++){  
  17.             System.out.println(Thread.currentThread().toString() + "..." + i);  
  18.             Thread.yield();//暂停当前正在执行的线程对象,并执行其他线程。  
  19.         }  
  20.     }  

基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究(Matlab代码实现)内容概要:本文围绕“基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究”展开,提出了一种结合数据驱动方法与Koopman算子理论的递归神经网络(RNN)模型线性化方法,旨在提升纳米定位系统的预测控制精度与动态响应能力。研究通过构建数据驱动的线性化模型,克服了传统非线性系统建模复杂、计算开销大的问题,并在Matlab平台上实现了完整的算法仿真与验证,展示了该方法在高精度定位控制中的有效性与实用性。; 适合人群:具备一定自动化、控制理论或机器学习背景的科研人员与工程技术人员,尤其是从事精密定位、智能控制、非线性系统建模与预测控制相关领域的研究生与研究人员。; 使用场景及目标:①应用于纳米级精密定位系统(如原子力显微镜、半导体制造设备)中的高性能预测控制;②为复杂非线性系统的数据驱动建模与线性化提供新思路;③结合深度学习与经典控制理论,推动智能控制算法的实际落地。; 阅读建议:建议读者结合Matlab代码实现部分,深入理解Koopman算子与RNN结合的建模范式,重点关注数据预处理、模型训练与控制系统集成等关键环节,并可通过替换实际系统数据进行迁移验证,以掌握该方法的核心思想与工程应用技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值