zoukankan      html  css  js  c++  java
  • java之结合代码理解synchronized关键字

    为了保证数据的一致性即实现线程的安全性,java虚拟机提供了同步和锁机制。synchronized关键字是最基本的互斥同步手段。除此之外,还可以使用java.util.concurrent包中的重入锁(ReentrantLock)来实现同步。相比synchronized,ReentrantLock增加了一些高级功能,主要有等待可中断、可实现公平锁、锁可以绑定多个条件等。

    见SynchronizedDemo.java的源码理解synchronized

    /**
     * Synchronized理解:
     *    根据如下4个例子总结如下:
     * Synchronized修饰的方法和Synchronized(this)修饰的代码块功能是一样的,当使用Synchronized修饰的方法或Synchronized(this)修饰的代码块被调用时,当前的实例对象被锁住,因此没有其他线程可以调用该实例对象的这个或任何其他的Synchronized修饰的方法和Synchronized(this)修饰的代码块
     * static Synchronized修饰的方法和Synchronized(*.class)修饰的代码块功能是一样的,当使用static Synchronized修饰的方法或Synchronized(*.class)修饰的代码块被调用时,当前的类对象(例子中的是Sync.class对象)被锁住,因此没有其他线程可以调用同一个类的的这个或任何其他的static Synchronized修饰的方法和Synchronized(*.class)修饰的代码块
     **/
    public class SynchronizedDemo{
        /**
         * 例1:
         * 同一个对象:
         * 当一个线程进入一个对象A的synchronized方法的同时,其它线程不能进入该对象的任何synchronized方法
         **/
        private void showSynchronizedResult1(){
            final Sync testSync1 = new Sync();
         
            Thread thread1 = new Thread(new Runnable(){
                @Override
                public void run(){
                    testSync1.run1();
                }
            });
    
            Thread thread2 = new Thread(new Runnable(){
                @Override
                public void run(){
                    testSync1.run2();
                }
            });
    
            thread1.start();
            thread2.start();
        }
        
        /**
         * 例2:
         * 同一个对象:
         * 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入该对象的普通方法
         **/
        private void showSynchronizedResult2(){
            final Sync testSync1 = new Sync();
         
            Thread thread1 = new Thread(new Runnable(){
                @Override
                public void run(){
                    testSync1.run1();
                }
            });
    
            Thread thread3 = new Thread(new Runnable(){
                @Override
                public void run(){
                    testSync1.run3();
                }
            });
    
            thread1.start();
            thread3.start();
        }
        
        /**
         * 例3:
         * 不同对象 
         * 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入其他对象的synchronized方法,互不影响
         **/
        private void showSynchronizedResult3(){
            final Sync testSync1 = new Sync();
            final Sync testSync2 = new Sync();
         
            Thread thread1 = new Thread(new Runnable(){
                @Override
                public void run(){
                    testSync1.run1();
                }
            });
    
            Thread thread2 = new Thread(new Runnable(){
                @Override
                public void run(){
                    testSync2.run2();
                }
            });
    
            thread1.start();
            thread2.start();
        }
        
        /**
         * 例4:
         * 当一个线程进入一个static synchronized方法的同时,其它线程不可以进入任何的static synchronized方法
         **/
        private void showStaticSynchronizedResult4(){
            Thread thread1 = new Thread(new Runnable(){
                @Override
                public void run(){
                    Sync.run4();
                }
            });
    
            Thread thread2 = new Thread(new Runnable(){
                @Override
                public void run(){
                    Sync.run5();
                }
            });
    
            thread1.start();
            thread2.start();
        }
        
        public static void main(String args[]){
            // 例1:多线程下同一对象的多个Synchronized方法
            new SynchronizedDemo().showSynchronizedResult1();
            
            // 例2:多线程下同一对象的Synchronized方法和普通方法
            //new SynchronizedDemo().showSynchronizedResult2();
            
            // 例3:多线程下不同对象的Synchronized方法
            //new SynchronizedDemo().showSynchronizedResult3();
            
            // 例4:多线程下的多个static Synchronized方法
            //new SynchronizedDemo().showStaticSynchronizedResult4();
        }
    }
    
    class Sync{
        public synchronized void run1(){
            for (int i = 0; i < 5; i++){
                System.out.println("execute run1");
                sleepOneSec();
            }
        }
    
        public synchronized void run2(){
            for (int i = 0; i < 5; i++){
                System.out.println("execute run2");
                sleepOneSec();
            }
        }
        
        public void run3(){
            for (int i = 0; i < 5; i++){
                System.out.println("execute run3");
                sleepOneSec();
            }
        }
        
        public static synchronized void run4(){
            for (int i = 0; i < 5; i++){
                System.out.println("execute run4");
                sleepOneSec();
            }
        }
    
        public static synchronized void run5(){
            for (int i = 0; i < 5; i++){
                System.out.println("execute run5");
                sleepOneSec();
            }
        }
        
        private static void sleepOneSec(){
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    详解GaussDB(for MySQL)服务:复制策略与可用性分析
    华为云的研究成果又双叒叕被MICCAI收录了!
    充分释放数据价值:安全、可信6到飞起
    未来云原生世界的“领头羊”:容器批量计算项目Volcano 1.0版本发布
    一文带你掌握OBS的两种常见的鉴权方式
    数据库实践丨MySQL多表join分析
    技术贴丨教你使用华为云鲲鹏服务器部署Discuz!论坛
    python Scrapy 从零开始学习笔记(二)
    python Scrapy 从零开始学习笔记(一)
    从零开始学Electron笔记(七)
  • 原文地址:https://www.cnblogs.com/bravestarrhu/p/java-----synchronized.html
Copyright © 2011-2022 走看看