重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本篇文章展示了java代码实现线程通信的具体操作,代码简明扼要容易理解,如果在日常工作遇到这个疑问。希望大家通过这篇文章,找到解决疑问的办法。
专注于为中小企业提供网站设计制作、做网站服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业农安免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了1000多家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
使用两个线程打印1-100,交替打印
涉及到的方法:
wait()--一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器
notify()--一旦执行此方法,就会唤醒wait的一个线程,如果有多个线程wait,就唤醒优先级高的
notifyAll()---一旦执行此方法,会唤醒所有被wait的线程
说明:
(1)实现线程通信wait()\notify()\notifyAll()三个方法必须使用在同步代码块或同步方法中
(2)上述三个代码的调用者必须是同步代码块或同步方法中的同步监视器
否则会出现异常java.lang.IllegalMonitorStateException
(3)wait()\notify()\notifyAll()在java.lang.Object类中
sleep()和wait()方法的异同
(1)相同点:一旦执行方法,都可以使当前线程进入阻塞状态
(2)不同点:
a)两个方法声明的位置不同:Thread类中声明sleep(),Object类中声明wait()
b)调用的要求不一样,sleep()可以在任何需要的场景调用,
wait()必须使用在同步代码块或同步方法中
c)关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中:
sleep()--不会释放锁,wait()会释放锁
d)sleep()时间到了,线程就被唤醒
wait()需要使用notify/notifyAll()来唤醒
public class CommunicationTest {
public static void main(String[] args) {
Number number=new Number();
Thread t1 = new Thread(number);
Thread t2 = new Thread(number);
t1.setName("线程1");
t2.setName("线程2");
t1.start();
t2.start();
}
class Number implements Runnable{
private int number=1;
private Object obj=new Object();
@Override
public void run() {
while(true){
// synchronized (this) {
synchronized (obj) {//调用notify的对象和同步监视器obj不是同一个对象,会出现异常
//加上obj.wait(),obj.notify()就对了
obj.notify();
if(number<=100){
System.out.println(Thread.currentThread().getName()+":"+number);
number++;
try {
//使得调用如下wait()方法的线程进入阻塞状态
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
}
}
}
释放锁的操作:
(1)当前线程的同步方法、同步代码块执行结束
(2)当前线程在同步代码块、同步方法中遇到break\return终止了该代码块,该方法继续执行
(3)当前线程在同步代码块、同步方法中出现了未处理的Error/Exception,导致异常结束
(4)当前线程在同步代码块、同步方法中执行类线程对象的wait()方法,当前线程暂停,并释放锁
不会释放锁的操作:
(1)线程执行同步代码块、同步方法时,调用Thread.sleep()\Thread.yield()方法暂停当前线程的执行
(2)线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁(同步监 视器)--尽量避免使用suspend、resume控制线程
以上就是java代码实现线程通信的详细内容了,看完之后是否有所收获呢?如果想了解更多相关内容,欢迎关注创新互联行业资讯!