简介:
在学习线程时,对wait(),notity(),notityAll()方法的使用感觉很懵,所以自己动手写了一个例子去一探究竟,这里分享出来,希望能对初学者有所帮助
疑惑:
问题①:方法如何使用
问题②:线程在等待的时候如果操作还未执行完,其他线程给它释放锁之后,它的操作结果是什么
问题③:启动其他线程后,对自身操作有没有影响
案例代码
public class Demo2 {
public Integer a = 1;
public static void main(String[] args) throws InterruptedException {
//模拟等待状态下,释放锁后数据的变化情况
Demo2 demo2 = new Demo2();
//线程一执行修改a
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (demo2){
System.out.println("进来时的a:"+demo2.a);
demo2.a = demo2.a+3;
try {
//等待
demo2.wait();
} catch (InterruptedException e) {
System.out.println("线程等待出错");
}
demo2.a++;
System.out.println("出去时a : "+demo2.a);
}
//验证释放锁后是否整个线程都在等待状态
System.out.println("我其它操作还在执行吗?");
}
});
thread1.start();
//主线程休眠一下再开启下一个线程,防止并发,确保线程一先执行
Thread.sleep(10);
//线程二也执行修改int,然后打开所有休眠中的线程
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (demo2){
System.out.println("二 进来时a:"+demo2.a);
demo2.a = demo2.a-2;
//启动等待线程一
demo2.notify();
demo2.a++;
System.out.println("二 执行结束a:"+demo2.a);
}
}
});
thread2.start();
}
}
初始使用时遇到错误:
①:java.long.IllegalMonitorStateException
//当前线程没有调用wait()/notify()对象的锁
解决:
百度查询,该方法是对加锁对象进行调用,不是对线程进行调用
总结:
①:wait()释放当前对象的锁,并让当前线程进入等待状态,其他拥有该对象锁的线程调用notify()方法时,那个等待中的线程才会再次启动
②:线程释放锁后,不会保留先前的执行结果,再次获得锁之后,继续执行剩下的操作
③:其他线程开启另一个线程时,对自身不会造成影响
理解:这个锁其实是在Demo2对象中的(jvm中的说法就是,在对象头中),所以是Demo2对象调用wait()方法,使自己的锁状态改成无锁状态,并把当前执行的加锁的线程进入等待状态,只有其他含有该对象锁的线程调用这个Demo2对象的notify()方法才能启动原先等待状态的线程,而那线程被释放后会继续来抢夺锁的所有权然后完成未完成的程序
以上就是小编的一些个人理解,如有不对的地方还望各位帮忙指出,谢谢