博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java线程:线程交互
阅读量:6199 次
发布时间:2019-06-21

本文共 3060 字,大约阅读时间需要 10 分钟。

一、基础知识

  java.lang.Object的类的三个方法:

    void notify():唤醒在此对象监视器上等待的单个线程。

    void notifyAll():唤醒在此对象监视器上等待的所有线程。

    void wait():导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法。

    void wait(long timeout):导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者是超过指定时间。

    void wait(long timeout,int nanos):导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者是其他某个线程中断当前线程,或超过某个实际时间。

以上方法使用要点:

  必须从同步环境中调用这些方法。线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。

  以上几种方法都是Object的实例方法,与每个对象具有锁是一样的,每个对象可以有一个线程列表,它们等待来自该信号。线程通过wait()获得这个等待列表。它不再执行任何其他指令,直到调用notify()为止。如果多个线程在同一个对象上等待,则将只选择一个线程继续执行。如果没有线程等待,则不采取操作。如;

  

1 package Thread; 2  3 public class Test2 { 4     public static void main(String[] args){ 5         ThreadB b=new ThreadB(); 6         b.start();//线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者 7         synchronized(b){ 8             try{ 9                 System.out.println("等待对象b完成计算...>");10                 b.wait();//当前线程A等待11             }catch(InterruptedException e){12                 e.printStackTrace();13             }14             System.out.println("b对象计算完毕,其总和是:"+b.total);15         }16     }17 }    18 class ThreadB extends Thread{19     int total;20     public void run(){21         synchronized(this){22             for(int i=0;i<101;i++){23                 total+=i;24             }25             notify();//(完成计算)唤醒在此对象监视器上等待的单个线程,在本例中A被唤醒。26         }27     }28 }
1 等待对象b完成计算...>2 b对象计算完毕,其总和是:5050

  在对象上调用wait()方法时,执行该代码的线程立刻放弃它在该对象的锁,然后调用调用notify()方法,如果线程仍然在完成同步代码,则线程移出之前不会放弃锁。因此,只要调用notify()并不意味着这时的锁变得可用。

二、多个线程在等待一个对象锁时使用notifyAll()

  多数情况下,最好通知等待某个对象的所有线程。如果这样做,可以在对象上使用notifyAll()方法,让所有等待的线程返回到可运行状态。如:

1 package Thread; 2  3 public class Test2 extends Thread{     4     public static void main(String[] args){ 5         Calculator calculator=new Calculator(); 6         new Test2(calculator).start(); 7         new Test2(calculator).start(); 8         new Test2(calculator).start(); 9         calculator.start();//线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者        10     }11     Calculator calculator;12     public Test2(Calculator calculator){13         this.calculator=calculator;14     }15     public void run(){16         synchronized(calculator){17             try{18                 System.out.println(Thread.currentThread()+"等待计算结果...>");19                 calculator.wait();//当前线程A等待20             }catch(InterruptedException e){21                 e.printStackTrace();22             }23             System.out.println(Thread.currentThread()+"结果为:"+calculator.total);24         }        25     }26 }    27 class Calculator extends Thread{28     int total;29     public void run(){30         synchronized(this){31             for(int i=0;i<101;i++){32                 total+=i;33             }34             notifyAll();//(完成计算)唤醒在此对象监视器上等待的单个线程,在本例中A被唤醒。35         }36     }37 }
View Code
1 Thread[Thread-1,5,main]等待计算结果...>2 Thread[Thread-3,5,main]等待计算结果...>3 Thread[Thread-2,5,main]等待计算结果...>4 Thread[Thread-2,5,main]结果为:50505 Thread[Thread-3,5,main]结果为:50506 Thread[Thread-1,5,main]结果为:5050
View Code

 

当神已无能为力,那便是魔渡众生

转载地址:http://dlnca.baihongyu.com/

你可能感兴趣的文章
jenkins 权限视野管理插件 —— role-strategy
查看>>
2015-郭辉-项目收尾+法律法规和标准
查看>>
nginx+tomcat负载均衡集群安装配置
查看>>
java定时器
查看>>
Ubuntu入门
查看>>
使用仓库管理器——Sonatype Nexus的九大理由
查看>>
ubuntu 使用故障排除记录
查看>>
我的友情链接
查看>>
winform 运用ZipFile解压文件
查看>>
F#初学笔记01
查看>>
有人向我反馈了一个bug
查看>>
[EDAS][HSF]开发 HSF 应用(EDAS SDK)
查看>>
Solidity陷阱:以太坊的随机数生成
查看>>
[数据结构复习]广义表
查看>>
appium问题归纳
查看>>
linux路由管理--专题
查看>>
【转】RDP 协议组件 X.224 在协议流中发现一个错误并且中断了客户端连接
查看>>
VMware NSX售价揭晓,启动渠道销售
查看>>
StarWind6完全图解安装与iSCSI配置
查看>>
MYSQL:ERROR 1148: The used command is not allowed with this MySQL version
查看>>