美文网首页程序员
[转] 浅析 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