最近打算深入学习一下并发编程,当看到synchronized关键字的时候,不明白synchronized 关键字到底锁住的什么。
网上查了下,也看了些文章,各种说法都有,更迷惑。synchronized可以放在类,静态方法,实例方法,或者代码块之前,这里就不一一介绍了,
经过测试,查找资料,总结一下感觉有用的东西。
A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
B.每个对象只有一个锁(lock)与之相关联。
C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
贴代码了
package test.concurrent;
public class TestSynchronized {
public void method1() throws InterruptedException {
System.out.println("method1 begin");
Thread.sleep(3000l);
System.out.println("method1 end");
}
public synchronized void method2() throws InterruptedException {
System.out.println("synchroized method2 begin");
Thread.sleep(5000l);
System.out.println("synchroized method2 end");
}
public static void main(String[] args) throws InterruptedException {
final TestSynchronized b = new TestSynchronized();
Runnable r1 = new Runnable() {
@Override
public void run() {
try {
b.method1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable r2= new Runnable() {
@Override
public void run() {
try {
b.method2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(r1).start();//Thread1
new Thread(r2).start();//Thread2
new Thread(r2).start();//Thread3
}
}
输出结果:
method1 begin
synchroized method2 begin
method1 end
synchroized method2 end
synchroized method2 begin
synchroized method2 end
当线程2调用synchronized方法的时候,线程3便处于阻塞状态,但并不影响线程1调用该对象未加锁的方法,直到线程2释放锁,线程3继续执行。
总结:
同步是围绕被称为内在锁(intrinsic lock)或者监视器锁(monitor lock)的内部实体构建的,强制对对象状态的独占访问,以及建立可见性所需的发生前关系。
Java提供了synchronized关键字来支持内在锁。
1.当synchronized方法被一个线程调用时,该线程获得该对象(若是静态方法,则该对象为Class对象)的内部锁。
2.当一个线程访问synchronized方法时,必须取得该对象的内部锁。若该锁被另一线程持有,则线程进入阻塞状态,等待另一线程释放锁。
3.一个对象只有一个内部锁。
欢迎加入高级程序员成长交流群 492362527