当前位置:编程学习 > JAVA >>

java 同步块(Java Synchronized Blocks)

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

主题包括的主要内容:

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

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

Instance methods
Static methods
Code blocks inside instance methods
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
&n

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,