2015-11-06 71 views
1

当这里的synchronized块不工作原理:无法在Thread类扩展到同步两个线程,但实现Runnable接口

class NewThreadt extends Thread { 
synchronized void dota(){ 
     for(int i = 5; i > 0; i--) 
     { 
     System.out.println(i); 
    try { 
     Thread.sleep(500); 

    } catch (InterruptedException e) { 
     System.out.println("Child interrupted."); 
    } 
     } 

    } 

    // This is the entry point for the second thread. 
    public void run() { 
    dota() ; 
    System.out.println("Exiting child thread."); 
    System.out.println(Thread.currentThread()); //gives the name of thread 

    } 
} 

class trial { 
    public static void main(String args[]) { 
    NewThreadt t=new NewThreadt(); 
    NewThreadt q=new NewThreadt(); 
    t.start(); 
    q.start(); both are in main 


    System.out.println("Main thread exiting."); 
    } 
} 

输出:

Main thread exiting. 
5 
5 
4 
4 
3 
3 
2 
2 
1 
1 

但是,当我做如下修改同步块的工作原理:

class NewThreadt implements Runnable //instead of class NewThreadt extends Thread 

NewThreadt abc=new NewThreadt(); //Changes in main() 
Thread t=new Thread(abc);  
Thread q=new Thread(abc); 
t.start(); 
q.start(); 

输出:

Main thread exiting. 
5 
4 
3 
2 
1  
5 
4 
3 
2 
1 

这是怎么发生的?这两个例子都不一样吗?

回答

3

同步取决于共享一个共同的锁。关于实例方法的​​关键字意味着要让线程进入该方法,它首先必须获取this上的锁。

在你的第一个例子中没有共享锁,两个线程中的每一个都锁定了它自己。每个线程获取自己的锁并且没有人阻塞,两个线程同时运行。 (这里唯一的锁定是,当一个线程想要写入控制台时,它必须先获取控制台的锁定,以便每个println都以原子方式发生。)

在第二个示例中,同一个Runnable被传入每个线程,因此它们都锁定在同一个对象Runnable上。一个线程获取锁并执行,另一个线程必须等待第一个线程释放锁。

如果你改变了第二个例子给每个线程独立的Runnable:

Thread t=new Thread(new NewThreadt());  
Thread q=new Thread(new NewThreadt()); 
t.start(); 
q.start(); 

然后你会看到同步不工作,它像第一个例子。

相关问题