2016-11-20 4 views
0
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

public class LockTest { 
    Lock lck=new ReentrantLock(); 

    public void lockIt(){ 
     lck.lock(); 

     for(int i=0;i<10;i++) { 
      System.out.println("i : "+ i); 
      try{Thread.sleep(200);} catch (Exception e){} 
     } 
     lck.unlock(); 
    } 

    public void test() 
    { 
     synchronized(this)  **// mark 1** 
     { 
      for(int j=0;j<10;j++) 
      { 
       System.out.println("val is"+j); 
       try{Thread.sleep(200);}catch (Exception e){} 
      } 
     } 
    } 

    public static void main(String[] args) { 
     LockTest obj=new LockTest(); 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       obj.lockIt(); 
      } 
     }).start(); 

     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       obj.test(); 
      } 
     }).start(); 

    } 
} 

} // Im obigen Fall, wenn wir lck.lock() sagen; dann wird Schloss auf welches Objekt tatsächlich erworben? ist es "das" oder das "lck" selbst?lock() -Methode erwirbt Sperren auf welchem ​​Objekt?

auch wenn das Schloss entweder auf "dieses" oder "lck" -Objekt erfasst wird, dann wie diff. Die Threads können in die kritischen Bereiche gelangen, die vom selben Objekt "this" oder "lck" gesperrt sind.

Fall 1: Wenn wir verwenden synchronisiert (das) bei MARK1 .. Fall 2: Wenn wir (LCK) bei Zeichen 1 ..

in beiden Fällen sowohl die Schlaufen läuft parallel synchronisiert Gebrauch.

+0

Werfen Sie einen Blick auf http://winterbe.com/posts/2015/04/30/java8-concurrency-tutorial-synchronized-locks-examples/. Die Antwort auf Ihre Frage ist, dass die Lock-Methode sicherstellt, dass auf den gesperrten Block nur von einem Thread zugegriffen werden kann. Es sperrt das eigentliche "Objekt" nicht, also ist "synchronisiert" ein anderer Ansatz. – Philipp

Antwort

3

Die Sperre erhalten durch lck.lock() (die auf der lck Objekt ist) ist durch synchronized(this) oder synchronized(lck) erhalten an das Schloss völlig unabhängig.

Wenn Sie kritische Abschnitte schützen möchten, müssen alle Threads den gleichen Sperrmechanismus (und die gleiche Sperre) verwenden.

java.util.concurrent.locks.Lock ist ein anderer Mechanismus für Fälle, in denen das Schlüsselwort synchronized nicht flexibel genug ist. Insbesondere erhält das Schlüsselwort synchronized automatisch Sperren und gibt sie frei, wenn die Ausführung einen Block erreicht und verlässt. Es ist nicht möglich, dort eine Sperre in einer Methode zu erhalten, sie irgendwo zu speichern, die Methode zu verlassen und die Sperre irgendwann wieder aufzuheben. Mit dem Objekt Lock können Sie diese Dinge tun (und es bietet auch Lock Wait Timeouts, während synchronized wird möglicherweise für immer blockieren).

+0

haben Sie Ihren Standpunkt. Vielen Dank :-) – gargPankaj

0

@Thilo hat das meiste davon beantwortet, nur um einen Punkt von Ihrem Code hinzuzufügen, stellen Sie sicher, dass Sie im Block entsperren, wie unten gezeigt, andernfalls besteht die Möglichkeit, dass Sie am Ende mit einem totes Schloss.

public void lockIt(){ 
    lck.lock(); 
    try { 
    for(int i=0;i<10;i++) { 
     System.out.println("i : "+ i); 
     try{Thread.sleep(200);}catch (Exception e){} 
    } 
    } finally { //important 
    if(lck != null) { 
     lck.unlock(); 
    } 
    } 
}