synchronized是用来解决同步问题:在处理共享资源时,如果多个线程在同时操作同一个资源,这时就会发生错误,java提供的解决方法时加同步锁,在一个时间点,只能有一个线程操作共享资源
package d1202;
public class SynTest {
/**
* 线程同步方法
* 1.不要将run置为同步方法,并行/并发编程串行
* public synchronized void run(){}
* 2.同步方法的监视器都是this
* 3.锁定一个方法时,其它同步方法也会锁定
*/
Object obj = new Object();
public synchronized void testA() throws InterruptedException { //this
System.out.println("AAA");
Thread.sleep(3000);
}
public void testB(){
synchronized (this){
System.out.println("BBB");
}
}
public void testC(){
synchronized (obj){
System.out.println("CCC");
}
}
}
package d1202;
public class SynControl {
public static void main(String[] args) {
final SynTest synTest = new SynTest();
Thread ta =new Thread(new Runnable() {
@Override
public void run() {
try {
synTest.testA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
ta.start();
Thread tb = new Thread(new Runnable() {
@Override
public void run() {
synTest.testB();
}
});
tb.start();
Thread tc = new Thread(new Runnable() {
@Override
public void run() {
synTest.testC();
}
});
tc.start();
}
}
打印BBB时会有5s的延迟,如代码A和B使用的时同一个锁this(同步方法锁默认时this本类),在执行A时this锁close,此时B不能进入同步代码块(进入阻塞等待CPU),C是的监视器是obj,不受监视器this的影响。
总结:
- 同步方法默认this或当前类class对象作为锁
- 同步代码块可以随意设置锁,不同步方法更细颗粒度,因此可以选择只同步部分问题代码
- 同步时高开销的操作,一般指同步问题代码,没有必要同步整个方法