Synchronized关键字的使用

2019-03-18  本文已影响0人  Lamour_a9c8

1.使用static关键字修饰synchronized,将锁升级成类级别的锁,获得是相同的锁,可以保证一个对象对应的方法执行完以后再执行其余对象的方法。处理锁争用的问题。只是用synchronized得到的是不同的锁,他们互不影响。

2.synchronized的锁重入,可以是在获得锁后再次请求可以再次获得该对象的锁。

public class SyncDubbo1 {

public synchronized void method1(){

System.out.println("method1..");

method2();

}

public synchronized void method2(){

System.out.println("method2..");

method3();

}

public synchronized void method3(){

System.out.println("method3..");

}

static class Main {

public int i = 10;

public synchronized void operationSup(){

try {

i--;

System.out.println("Main print i = " + i);

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

static class Sub extends Main {

public synchronized void operationSub(){

try {

while(i > 0) {

i--;

System.out.println("Sub print i = " + i);

Thread.sleep(100);

this.operationSup();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

3.对于异常的处理分两种情况,一是原子性则要抛出异常,二是使用continue跳过。

4.synchronized代码块,优化代码执行时间,减小锁的粒度。

5.使用synchronized时需要注意到的问题

不要使用string常量加锁,会出现死循环问题

不要再代码块中修改锁中的对象,属性改变不影响。

死锁问题,在设计程序时就应该避免双方相互持有对方的锁的情况

synchronized只是一个内置锁的加锁机制,当某个方法加上synchronized关键字后,就表明要获得该内置锁才能执行,并不能阻止其他线程访问不需要获得该内置锁的方法。

6.三种使用方式

public void method1(){

synchronized (this) { //对象锁

try {

System.out.println("do method1..");

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public void method2(){ //类锁

synchronized (ObjectLock.class) {

try {

System.out.println("do method2..");

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

private Object lock = new Object();

public void method3(){ //任何对象锁

synchronized (lock) {

try {

System.out.println("do method3..");

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

7.synchronized的缺陷

当某个线程进入同步方法获得对象锁,那么其他线程访问这里对象的同步方法时,必须等待或者阻塞,这对高并发的系统是致命的,这很容易导致系统的崩溃。如果某个线程在同步方法里面发生了死循环,那么它就永远不会释放这个对象锁,那么其他线程就要永远的等待。这是一个致命的问题。

上一篇下一篇

猜你喜欢

热点阅读