zoukankan      html  css  js  c++  java
  • java 同步块(Java Synchronized Blocks)

    java 同步块(Java Synchronized Blocks)

    Java 同步块包括方法同步和代码块同步。java 同步可以避免资源竞争,避免死锁。

    主题包括的主要内容:

    The Java synchronized Keyword

    在java中,同步是用 synchronized 关键字代表的. 同步是针对对象和类来说的。一个对象上的所有同步块只能被一个线程锁住。其他所有的线程试图访问同步块的方法,都要等到占用资源的线程释放了才能访问。

    synchronized关键字可以用到4个种场景:

    1. Instance methods
    2. Static methods
    3. Code blocks inside instance methods
    4. Code blocks inside static methods

    Synchronized Instance Methods

    Here is a synchronized instance method:

      public synchronized void add(int value){
          this.count += value;
      }
    

    当一个方法上用到synchronized关键字,Java才能知道它是个同步方法。

    一个实例同步方法只属于实例本身。每个实例都有自己的同步方法。

    Synchronized Static Methods

    Static methods are marked as synchronized just like instance methods using thesynchronized keyword. Here is a Java synchronized static method example:

      public static synchronized void add(int value){
          count += value;
      }
    

    同样 synchronized 告诉Java 这是一个同步方法。

    同步静态方法属于类对象。在VM中只有一个类对象,因此只能有一个线程执行静态同步方法。

    Synchronized Blocks in Instance Methods

    有时候, 不需要同步整个方法,只需要同步方法里面的一部分,可以借助同步块来完成工作。

    Here is a synchronized block of Java code inside an unsynchronized Java method:

      public void add(int value){
    
        synchronized(this){
           this.count += value;   
        }
      }
    

    这个例子是用同步块标记一块同步代码。这个同步块代码就相当于同步方法。

    Notice how the Java synchronized block construct takes an object in parentheses. In the example "this" is used, which is the instance the add method is called on. The object taken in the parentheses by the synchronized construct is called a monitor object. The code is said to be synchronized on the monitor object. A synchronized instance method uses the object it belongs to as monitor object.

    对于同一个对象只能有一个线程访问同步块。

    下面两个方法的代码,效果是一样的。

     
      public class MyClass {
      
        public synchronized void log1(String msg1, String msg2){
           log.writeln(msg1);
           log.writeln(msg2);
        }
    
      
        public void log2(String msg1, String msg2){
           synchronized(this){
              log.writeln(msg1);
              log.writeln(msg2);
           }
        }
      }
    

    只能有一个线程执行(针对同一个对象) ;

    第二个方法是不同的线程执行的时候会在同步块里面发生等待(针对同一对象)。

    Synchronized Blocks in Static Methods

    下面两个静态方法是在类对象上的:

      public class MyClass {
    
        public static synchronized void log1(String msg1, String msg2){
           log.writeln(msg1);
           log.writeln(msg2);
        }
    
      
        public static void log2(String msg1, String msg2){
           synchronized(MyClass.class){
              log.writeln(msg1);
              log.writeln(msg2);  
           }
        }
      }
    

    一个线程只能在同一时间执行上面的任何一个方法。

    对于第二个方法:只能有一个线程在代码块里面执行。

    Java Synchronized Example


      public class MyClass {
    
    
        public static synchronized void log1(String msg1, String msg2){
    	 try {
    	    	    TimeUnit.SECONDS.sleep(5) ;
    	    	} catch (InterruptedException e) {
    	    	    e.printStackTrace();
    	    	}
           System.out.println(msg1);
           System.out.println(msg2);
        }
        
        public static synchronized void log3(String msg1, String msg2){
    	    System.out.println(msg1);
    	    System.out.println(msg2);  
        }
      
        public static void log2(String msg1, String msg2){
           synchronized(MyClass.class){
    	   try {
    	    	    TimeUnit.SECONDS.sleep(3) ;
    	    	} catch (InterruptedException e) {
    	    	    e.printStackTrace();
    	    	}
    	   System.out.println(msg1);
    	   System.out.println(msg2);  
           }
        }
        
        public static void log4(String msg1, String msg2){
    	synchronized(MyClass.class){
    	    
    	    System.out.println(msg1);
    	    System.out.println(msg2);  
    	}
        }
        
       
        public void log5(String msg1, String msg2){
    	synchronized(this){
    	    System.out.println(msg1);
    	    System.out.println(msg2);  
    	}
        }
        
      }
      public class SynchronizedTest {
    
    
        Thread t1 = new Thread(new Runnable() {
            
            @Override
            public void run() {
              
                MyClass.log1("msg11", "msg12") ;
            }
        }) ;
        Thread t2 = new Thread(new Runnable() {
            
            @Override
            public void run() {
               
                MyClass.log2("msg21", "msg22") ;
            }
        }) ;
        Thread t3 = new Thread(new Runnable() {
    	
    	@Override
    	public void run() {
    	    
    	    MyClass.log3("msg31", "msg32") ;
    	}
        }) ;
        
        Thread t4 = new Thread(new Runnable() {
    	
    	@Override
    	public void run() {
    	    
    	    MyClass.log4("msg41", "msg42") ;
    	}
        }) ;
        
        Thread t5 = new Thread(new Runnable() {
    	
    	@Override
    	public void run() {
    	    
    	   new  MyClass().log5("msg51", "msg52") ;
    	}
        }) ;
        
        public static void main(String[] args) {
    	SynchronizedTest st = new SynchronizedTest() ;
    	
    	st.t1.start() ;
    //	st.t3.start() ;
    	
    //	st.t2.start() ;
    //	st.t4.start() ;
    	st.t5.start() ;
    	
    	
    	 int i = 0 ;
    		while(true){
    		    try {
    			TimeUnit.SECONDS.sleep(1) ;
    			System.out.println("---------------> " + i);
    			i ++ ;
    			
    		    } catch (InterruptedException e) {
    			e.printStackTrace();
    		    }
    		    if(i > 10 ){
    			    break ;
    		    }
    		}
    		
    	
    	
        }
        
    }
    

    测试组合:

    1. 测试实例方法组合;

    2. 测试静态方法组合;

    3. 测试实例方法和静态方法组合;(注意方法里面的 sleep, 是为了做到更好的测试效果)。

  • 相关阅读:
    “main cannot be resolved or is not a field”解决方案
    .net学习笔记----有序集合SortedList、SortedList<TKey,TValue>、SortedDictionary<TKey,TValue>
    MVC学习笔记---ModelBinder
    MVC学习笔记---MVC框架执行顺序
    服务器知识----IIS架设问题
    C/C++学习笔记---primer基础知识
    C/C++学习笔记----指针的理解
    C#学习笔记-----C#枚举中的位运算权限分配
    CSS学习笔记----CSS3自定义字体图标
    Clr Via C#读书笔记----基元线程同步构造
  • 原文地址:https://www.cnblogs.com/java20130722/p/3207237.html
Copyright © 2011-2022 走看看