public class TestSynchronized {
public static void main(String[] args){
final Object A=new Object();
ExecutorService exec = Executors.newFixedThreadPool(4);
Runnable add = new Runnable() {
volatile int i=0;
public void run() {
i++;
System.out.println("Pre " + Thread.currentThread().getName()+" i="+i);
synchronized (A){
try {
System.out.println("sleep" + Thread.currentThread().getName());
A.wait(1000);//释放锁
System.out.println("wake up" + Thread.currentThread().getName());
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("Post " + Thread.currentThread().getName());
}
}
}
};
for(int index = 0; index < 4; index++)
exec.submit(add);
exec.shutdown();
}
}
输出
Pre pool-1-thread-1 i=3
Pre pool-1-thread-4 i=4
Pre pool-1-thread-3 i=3
Pre pool-1-thread-2 i=3
sleeppool-1-thread-1
sleeppool-1-thread-2
sleeppool-1-thread-3
sleeppool-1-thread-4
wake uppool-1-thread-2
Post pool-1-thread-2
wake uppool-1-thread-3
Post pool-1-thread-3
wake uppool-1-thread-4
Post pool-1-thread-4
wake uppool-1-thread-1
Post pool-1-thread-1
都使用A对象进行加锁,任何对象都可以用来加锁,但记得使用同一个对象。否则每个都有自己的锁失去意义。
每个线程都共享add对象,所以i才能到3,4.另外看出来 volatile并不保证操作的原子性,只是保证可见性。
wait会释放锁,所以sleep,wake可以不用连在一起,而sleep不会释放锁,所以wake和post一定连在一起
转载请注明原文地址: https://ju.6miu.com/read-6556.html