美文网首页程序员
[转] 浅析 synchronized 用法 -- 锁住的是类还

[转] 浅析 synchronized 用法 -- 锁住的是类还

作者: 殷天文 | 来源:发表于2018-09-25 17:07 被阅读48次

原文:https://www.cnblogs.com/QQParadise/articles/5059824.html

使用 synchronized 写个同步方法,很轻松的能解决一些多线程问题。但是 synchronized 究竟锁住的是类(全局锁)还是对象?只要加上 synchronized 就能保证线程安全吗?

demo1 (三个线程 操作三个 Sync 对象)

class Sync {

    public synchronized void test() {
        System.out.println(Thread.currentThread().getName() + "开始..");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "结束..");
    }
}

class MyThread extends Thread {

    public void run() {
        Sync sync = new Sync();
        sync.test();
    }
}

public class Main {

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            Thread thread = new MyThread();
            thread.start();
        }
    }
}
运行结果
Thread-2开始..
Thread-1开始..
Thread-0开始..
Thread-2结束..
Thread-1结束..
Thread-0结束..

可以看到三个线程,操作三个对象,这时候 synchronized 并不起作用...

改造
  • 使用 synchronized(this){},这边我直接剧透了,结果一样...

demo2 (三个线程 操作同一个 Sync 对象)

class Sync {

    public void test() {
        synchronized(this) {
            System.out.println(Thread.currentThread().getName() + "开始..");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "结束..");
        }
    }
}

class MyThread extends Thread {  
      
    private Sync sync;  
  
    public MyThread(Sync sync) {  
        this.sync = sync;  
    }  
  
    public void run() {  
        sync.test();  
    }  
}  
  
public class Main {  
  
    public static void main(String[] args) {  
        Sync sync = new Sync();  
        for (int i = 0; i < 3; i++) {  
            Thread thread = new MyThread(sync);  
            thread.start();  
        }  
    }  
}  
运行结果
Thread-0开始..
Thread-0结束..
Thread-2开始..
Thread-2结束..
Thread-1开始..
Thread-1结束..
改造
  • 使用 synchronized 修饰方法,结果一样...
小结

从上面两个例子来看,其实 synchronized 修饰方法 和 synchronized(this){} 锁的是对象

demo3 synchronized 全局锁(锁类)

class Sync {

    public void syncTest() {
        // 或者是 this.getClass()
        synchronized (Sync.class) {
            System.out.println(Thread.currentThread().getName() + "开始..");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "结束..");
        }
    }
    
    public static synchronized void staticTest() {
        System.out.println(Thread.currentThread().getName() + "开始..");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "结束..");
    }
    
}

class MyThread extends Thread {

    public void run() {
        Sync sync = new Sync();
        sync.syncTest();
//        Sync.staticTest();
    }
}

public class Main {

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            Thread thread = new MyThread();
            thread.start();
        }
    }
}

分别执行两个方法,这时候都实现了全局锁(锁住了类)

Thread-0开始..
Thread-0结束..
Thread-2开始..
Thread-2结束..
Thread-1开始..
Thread-1结束..
总结
  • synchronized 修饰方法 和 synchronized(this){} 锁的是对象
  • static synchronized 修饰方法 和 synchronized(this.getClass()){} 是全局锁

相关文章

网友评论

    本文标题:[转] 浅析 synchronized 用法 -- 锁住的是类还

    本文链接:https://www.haomeiwen.com/subject/oirloftx.html