1.方法wait()锁释放与notify()锁不释放
当方法wait()被执行后,锁被自动释放,但执行完notify()方法,锁却不自动释放。
示例代码如下:
package threadTest;
/**
* @Author LiBinquan
*/
public class Service {
public void testMethod(Object lock){
try{
synchronized (lock){
System.out.println("begin wait()");
lock.wait();
System.out.println("end wait()");
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
线程a:
package threadTest;
/**
* @Author LiBinquan
*/
public class ThreadA extends Thread{
private Object lock;
public ThreadA(Object lock){
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.testMethod(lock);
}
}
线程b:
package threadTest;
/**
* @Author LiBinquan
*/
public class ThreadB extends Thread{
private Object lock;
public ThreadB(Object lock){
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.testMethod(lock);
}
}
运行类:
package threadTest;
/**
* @Author LiBinquan
*/
public class Run {
public static void main(String[] args) {
Object lock = new Object();
ThreadA a = new ThreadA(lock);
a.start();
ThreadB b = new ThreadB(lock);
b.start();
}
}
输出:
如果将wait方法改成sleep方法,就成了同步效果,代码如下:
package threadTest;
/**
* @Author LiBinquan
*/
public class Service {
public void testMethod(Object lock){
try{
synchronized (lock){
System.out.println("begin wait()");
Thread.sleep(1000);
System.out.println("end wait()");
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
输出:
方法notify()被执行后,不释放锁。
package threadTest;
/**
* @Author LiBinquan
*/
public class Service {
public void testMethod(Object lock){
try{
synchronized (lock){
System.out.println("begin wait() ThreadName = "+Thread.currentThread().getName());
lock.wait();
System.out.println("end wait() ThreadName = "+Thread.currentThread().getName());
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void synNotifyMethod(Object lock){
try{
synchronized (lock){
System.out.println("begin notify() ThreadName = "+Thread.currentThread().getName()+" time = "+System.currentTimeMillis());
lock.notify();
Thread.sleep(5000);
System.out.println("end notify() ThreadName = "+Thread.currentThread().getName()+" time = "+System.currentTimeMillis());
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
线程a:
package threadTest;
/**
* @Author LiBinquan
*/
public class ThreadA extends Thread{
private Object lock;
public ThreadA(Object lock){
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.testMethod(lock);
}
}
线程NotifyThread
package threadTest;
/**
* @Author LiBinquan
*/
public class NotifyThread extends Thread{
private Object lock;
public NotifyThread(Object lock){
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.synNotifyMethod(lock);
}
}
线程SynNotifyMethodThread:
package threadTest;
/**
* @Author LiBinquan
*/
public class SynNotifyMethodThread extends Thread{
private Object lock;
public SynNotifyMethodThread(Object lock){
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.synNotifyMethod(lock);
}
}
运行类:
package threadTest;
/**
* @Author LiBinquan
*/
public class Run {
public static void main(String[] args) {
Object lock = new Object();
ThreadA a = new ThreadA(lock);
a.start();
NotifyThread b = new NotifyThread(lock);
b.start();
SynNotifyMethodThread c = new SynNotifyMethodThread(lock);
c.start();
}
}
输出:
由输出可得,必须执行完notify方法所在的同步synchronized代码后才释放锁。
2.当interrupt方法遇到wait方法
当线程呈wait()状态时,调用线程对象的interrupt()方法会出现InterruptedException异常。
测试代码如下:
package threadTest;
/**
* @Author LiBinquan
*/
public class ServiceTwo {
public void testMethod(Object lock){
try{
synchronized (lock){
System.out.println("begin wait()");
lock.wait();
System.out.println(" end wait");
}
}catch (InterruptedException e){
e.printStackTrace();
System.out.println("出现异常了,因为wait状态的线程被interrupt了!");
}
}
}
线程a:
package threadTest;
/**
* @Author LiBinquan
*/
public class ThreadA extends Thread{
private Object lock;
public ThreadA(Object lock){
super();
this.lock = lock;
}
@Override
public void run() {
ServiceTwo service = new ServiceTwo();
service.testMethod(lock);
}
}
运行类:
package threadTest;
/**
* @Author LiBinquan
*/
public class Run {
public static void main(String[] args) {
try{
Object lock = new Object();
ThreadA a = new ThreadA(lock);
a.start();
Thread.sleep(5000);
a.interrupt();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
输出:
总结如下:
1.执行完同步代码块就会释放对象的锁。
2.在执行同步代码块的过程中,遇到异常而导致线程终止,锁也会被释放。
3.在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放对象锁,而此线程对象会进入线程等待池中,等待被唤醒。