在面试中经常性的遇到wait和sleep的区别?
1.sleep不会释放锁 ,而wait会释放锁
private static final String LOCK = "lock";
public static void main(String[] args) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "====start");
test();
System.out.println(Thread.currentThread().getName() + "====end");
}).start();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "====start");
test();
System.out.println(Thread.currentThread().getName() + "=====end");
}).start();
}
public static void test() {
synchronized (LOCK) {
System.out.println(Thread.currentThread().getName() + "====getLock" + System.currentTimeMillis());
try {
LOCK.wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "====unLock" + +System.currentTimeMillis());
}
}
Thread-0====start
Thread-0====getLock1603173719697
Thread-1====start
Thread-1====getLock1603173719697
Thread-1====unLock1603173724698
Thread-1=====end
Thread-0====unLock1603173724698
Thread-0====end
private static final String LOCK = "lock";
public static void main(String[] args) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "====start");
test();
System.out.println(Thread.currentThread().getName() + "====end");
}).start();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "====start");
test();
System.out.println(Thread.currentThread().getName() + "=====end");
}).start();
}
public static void test() {
synchronized (LOCK) {
System.out.println(Thread.currentThread().getName() + "====getLock" + System.currentTimeMillis());
try {
Thread.sleep(4321L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "====unLock" + +System.currentTimeMillis());
}
}
Thread-0====start
Thread-1====start
Thread-1====getLock1603173961122
Thread-1====unLock1603173965444
Thread-1=====end
Thread-0====getLock1603173965444
Thread-0====unLock1603173969765
Thread-0====end
2.由上面的代码 我们发现sleep方法是通过Thead的静态方法 而wait是Object对象的方法
3.我们将同步块去掉 会发现sleep方法会正常使用,而wait方法会出错(wait必须依赖同步块)
public static void test() {
System.out.println(Thread.currentThread().getName() + "====getLock" + System.currentTimeMillis());
try {
LOCK.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "====unLock" + +System.currentTimeMillis());
}
Thread-0====start
Thread-1====start
Thread-1====getLock1603174303023
Thread-0====getLock1603174303023
Exception in thread "Thread-1" Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at com.zexiang.java.sync.reentrantsync.T.test(T.java:31)
at com.zexiang.java.sync.reentrantsync.T.lambda$main$0(T.java:17)
at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at com.zexiang.java.sync.reentrantsync.T.test(T.java:31)
at com.zexiang.java.sync.reentrantsync.T.lambda$main$1(T.java:22)
at java.lang.Thread.run(Thread.java:745)
4.sleep必须设置时间 而wait则可以都可以 。如果不给时间参数必须要唤醒LOCK.notify();
Thread.sleep(1000);
LOCK.wait(1000);
LOCK.wait();