Synchronized作用、用法、性质、原理、缺陷

Synchronized作用:

能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。

 

Synchronized两个用法:

1、对象锁:

Synchronized作用、用法、性质、原理、缺陷

包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)。

同步代码块形式:

public class SynchronizedObjectCodeBlock implements Runnable {

    static SynchronizedObjectCodeBlock instance = new SynchronizedObjectCodeBlock();
    Object lock1 = new Object();
    Object lock2 = new Object();

    @Override
    public void run() {
        synchronized (lock1) {
            System.out.println("lock1,我叫:" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " lock1运行结束。");
        }

        synchronized (lock2) {
            System.out.println("lock2,我叫:" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " lock2运行结束。");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");

    }
}

Synchronized作用、用法、性质、原理、缺陷

方法锁形式(synchronized 修饰普通方法,不能是静态方法):

public class SynchronizedObjectMethod implements Runnable{
    static SynchronizedObjectMethod instance = new SynchronizedObjectMethod();

    @Override
    public void run() {
      method();
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");

    }

    public synchronized void method(){
        System.out.println("我的对象锁的方法修饰符形式,我叫:"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "运行结束。");
    }

}

Synchronized作用、用法、性质、原理、缺陷

2、类锁:

Synchronized作用、用法、性质、原理、缺陷

Synchronized作用、用法、性质、原理、缺陷

指Synchronized修饰静态的方法或指定锁为Class对象

静态方法:

public class SynchronizedClassStatic implements Runnable{

    static SynchronizedClassStatic instance1 = new SynchronizedClassStatic();
    static SynchronizedClassStatic instance2 = new SynchronizedClassStatic();

    @Override
    public void run() {
        method();
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");

    }

    public static synchronized void method(){
        System.out.println("我是类锁的第一种形式:static形式,我叫:"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "运行结束。");
    }
}

Synchronized作用、用法、性质、原理、缺陷

Class对象:

public class SynchronizedClassClass implements Runnable {

    static SynchronizedClassClass instance1 = new SynchronizedClassClass();
    static SynchronizedClassClass instance2 = new SynchronizedClassClass();

    @Override
    public void run() {
        method();
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(instance1);
        Thread t2 = new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive() || t2.isAlive()) {

        }
        System.out.println("finished");

    }

    public void method() {
        synchronized (SynchronizedClassClass.class) {
            System.out.println("我是类锁的第二种形式:class形式,我叫:" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "运行结束。");
        }
    }
}

Synchronized作用、用法、性质、原理、缺陷

 

Synchronized性质

1、可重入

Synchronized作用、用法、性质、原理、缺陷(粒度scope,可理解为范围)

可重入通俗解释:

在北京和上海给车子上牌,需要给车子摇号,摇到号相当于线程获取到了锁,但是家里有3辆车都想上牌,摇到一次号只能上一个车,摇到一次车牌就想上三辆车是不可以的,称为不可重入;如果摇号是可重入的,摇到一个号就可以一直获取车牌,直到自己不愿意获取,则称为可重入。

一个线程拿到一个锁,就可以一直用,为可重入;一个线程拿到一个锁,用了一次需要先释放再和其他线程竞争,为不可重入。

 

2、不可中断

Synchronized作用、用法、性质、原理、缺陷

PS:LOCK类可以拥有中断的能力

 

Synchronized原理

1、加锁和释放锁的原理

public class SynchronizedToLock {

    Lock lock = new ReentrantLock();

    //第一个方法和第二个方法是等价的,第二个方法相当于解剖第一个方法
    public synchronized void method1() {
        System.out.println("我是synchronized形式的锁");
    }

    public void method2() {
        lock.lock();
        try {
            System.out.println("我是lock形式的锁");
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        SynchronizedToLock s = new SynchronizedToLock();
        s.method1();
        s.method2();
    }
}

Synchronized作用、用法、性质、原理、缺陷

2、可重入原理

Synchronized作用、用法、性质、原理、缺陷

3、可见性原理

Synchronized作用、用法、性质、原理、缺陷

JMM为java内存模型的缩写

Synchronized修饰的代码块或方法,在执行完毕后,被锁住的对象所做的任何修改,都需要在释放锁之前从线程内存写回到主内存中。

 

Synchronized缺陷

Synchronized作用、用法、性质、原理、缺陷