2013-06-29 80 views
1

在下面的代码,我试图找出线程在synchronized块处理执行:线程执行序列

public class ThreadExp { 
    public static void main(String[] args) throws InterruptedException { 
     MyRunnable r = new MyRunnable(); 
     Thread t1 = new Thread(r, "Thread1"); 
     Thread t2 = new Thread(r, "Thread2"); 
     t1.start(); 
     t2.start(); 
    } 

} 

class MyRunnable implements Runnable { 

    @Override 
    public void run() { 
     callFn(); 
    } 

    private void callFn() { 
     System.out.println(Thread.currentThread().getName() + ": entered callSync()"); 
     synchronized (Thread.currentThread()) { 
      System.out.println(Thread.currentThread().getName() + ": inside sync"); 
      try { 
       Thread.currentThread().sleep(5000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println(Thread.currentThread().getName() + " leaving sync"); 
     } 
     System.out.println(Thread.currentThread().getName() + ": leaving callSync()"); 
    } 
} 

实际输出:

Thread1: entered callFn() 
    Thread2: entered callFn() 
    Thread1: inside sync block 
    Thread2: inside sync block 
// 5000 millisec sleep 
    Thread2 leaving sync block 
    Thread1 leaving sync block 
    Thread2: leaving callFn() 
    Thread1: leaving callFn() 

而我预期的东西如:

Thread1: entered callFn() 
Thread2: entered callFn() 
Thread1: inside sync block 
// 5000 millisec sleep 
Thread1 leaving sync block 
Thread1: leaving callFn() 
Thread2: inside sync block 
Thread2 leaving sync block 
Thread2: leaving callFn() 

总的来说,我认为Thread1会获得锁,然后进入睡眠。只有在线程1完成后,线程2才能进入同步块。

+0

同步线程对象将永远不会阻塞。它怎么可能?多线程尝试输入锁时发生争用,但在您的情况下,每个线程正在输入唯一的锁。 – dlev

回答

5

正在同步线程本身上:

synchronized (Thread.currentThread()) 

所以每个线程都有自己的锁,他们可以同时执行​​块。

如果您希望​​块一次只能由一个线程运行,则需要使用相同的锁。

在您的例子,它可能仅仅是this,因为Runnable实例同样为你的两个线程:

synchronized(this) {...} 

然后输出如下:当前

Thread1: entered callSync() 
Thread1: inside sync 
Thread2: entered callSync() 
Thread1 leaving sync 
Thread1: leaving callSync() 
Thread2: inside sync 
Thread2 leaving sync 
Thread2: leaving callSync() 
+0

在Thread.currentThread()上同步似乎完全没用 - 坦率地说,看起来像一个错误。有没有这种情况有用? – user949300

+0

@ user949300它所做的是创建一个内存屏障,但有很多更好的方法来实现它。 – assylias

+0

谢谢 - 它的使用有点意义。 – user949300