Lock和synchronized区别:
Lock能提供更多API,如trylock():返回true表示拿到锁,false表示没有拿到锁;trylock(long time, TimeUnit unit):定义超时时间,避免死锁;unlock():上锁后要在finally中调用unlock()去掉锁。sleep和wait的区别:两者对线程的占用不同,看下面的代码:
public class Consumer implements Runnable{
public void run() {
// TODO Auto-generated method stub
int count = 10;
while(count > 0) {
synchronized (Test. obj) {
System. out.print( "Consumer");
count --;
//Test. obj.notify();
try {
Test. obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class Produce implements Runnable{
public void run() {
// TODO Auto-generated method stub
int count = 10;
while(count > 0) {
synchronized (Test. obj) {
//System.out.print("count = " + count);
System. out.print( "Produce");
count --;
//Test. obj.notify();
try {
Test. obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class Test {
public static final Object obj = new Object();
public static void main(String[] args) {
new Thread( new Produce()).start();
new Thread( new Consumer()).start();
}
}
produce那个runnable先执行,之后wait,此时会释放obj的锁,然后Consumer拿到obj的锁,开始执行,最后结果:
ProduceConsumer
执行到Consumer就结束了,其实程序这时还在运行中,只是处于挂起状态,下面再在Consumer中加入notify:
public class Consumer implements Runnable{
public void run() {
// TODO Auto-generated method stub
int count = 10;
while(count > 0) {
synchronized (Test. obj) {
System. out.print( "Consumer");
count --;
//挂起前释放锁
Test. obj.notify();
try {
Test. obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
运行结果:
ProduceConsumerProduce
说明Consumer释放了对象锁,Produce重新拿到锁,那么为了让这两个线程轮流执行,每次wait前释放对象锁,即在wait前,调用notify:
public class Produce implements Runnable{
public void run() {
// TODO Auto-generated method stub
int count = 10;
while(count > 0) {
synchronized (Test. obj) {
//System.out.print("count = " + count);
System. out.print( "Produce");
count --;
Test.obj.notify();
try {
Test. obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class Consumer implements Runnable{
public void run() {
// TODO Auto-generated method stub
int count = 10;
while(count > 0) {
synchronized (Test. obj) {
System. out.print( "Consumer");
count --;
Test. obj.notify();
try {
Test. obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
结果:
ProduceConsumerProduceConsumerProduceConsumerProduceConsumerProduceConsumerProduceConsumerProduceConsumerProduceConsumerProduceConsumerProduceConsumer
sleep是线程的方法,线程调用后会让出cpu时间片,但并不能操作对象释放对象锁。