2011-12-17 63 views
1

我是Java新手。下面是一个代码作为线程和同步的例子。线程和同步示例

public class A implements Runnable{ 
    public synchronized void run(){ 

     /* 
     some code here 
     */ 

    } 
} 

public class B { 
    public static void main(String[] args){ 
     A obj1 = new A(); 
     Thread t = new Thread(obj1); 
     A obj2 = obj1; 
     Thread t1 = new Thread(obj2); 
     t.start(); 
     t1.start(); 
    } 
} 

现在这两个线程会为相同的锁相互阻塞还是会得到两个不同的锁?

谢谢!

+2

你为什么不自己运行的代码,并找到问题的答案? – Paul 2011-12-17 01:57:41

+0

@保罗 - 因为这不会给出一个**明确的**答案。它会告诉你它*看起来像*一个线程阻塞另一个,*每次*你运行它。但是并没有告诉OP有*实际*阻塞(与OP不知道的其他假设机制截然不同),或阻塞*总是*发生。 – 2011-12-17 02:13:19

+1

@Paul - 我想说的是,将同步视为黑盒子并试图弄清楚如何在实验中使用它,这不是一个完美的方法。你有可能得到各种虚假的想法......这会在稍后引起你的注意。 – 2011-12-17 02:16:01

回答

8

(首先,请坚持Java编码惯例。一个类名应该总是开始以一个大写字母,没有例外。)

只有一个线程将同时执行的run()方法。

A.run()方法是一种实例方法,它被声明为​​。这两个事实意味着它将在进入方法体之前获得对this(即A的实例)的锁定,并在退出时释放它。总之,run()this

因此,在您的主程序中,您将创建一个单一的A实例并将其作为两个线程的target对象传递。他们都需要在同一个对象上执行run()方法,并且这不能同时发生......按照前一段的推理。

这不是必然意味着一个线程会阻塞另一个线程。在第二个线程准备好尝试呼叫之前,第一个要启动的线程也可能会完成其run()呼叫。但我们可以说... 明确地 ...两个线程对run()的调用不会在时间上重叠。

0

他们将互相阻止,因为他们都在同一个对象​​。

例如,此程序:

public class Foo 
{ 
    public static void main(final String... args) 
    { 
     final Runnable r = 
      new Runnable() 
      { 
       public synchronized void run() 
       { 
        for(int i = 0; i < 10; ++i) 
        { 
         System.out.println(i); 
         try 
          { Thread.sleep(1000L); } 
         catch(final InterruptedException ie) 
          { throw new RuntimeException(ie); } 
        } 
       } 
      }; 
     new Thread(r).start(); 
     new Thread(r).start(); 
    } 
} 

将通过9打印0,暂停对数之后的第二,然后再做一次。它将不是交错两组数字。

0

同步迫使线程按顺序(块)运行。

根据定义,同步意味着方法“一次一个”地运行。在第二个线程(可能是“t1”)的run()方法被输入之前,第一个要执行的线程(可能是“t”)将会完成。

要测试的同步效果:

运行将是填补了调用run()方法来

Thread.sleep(1000); 

然后运行与您的代码最好的实验,并没有“同步”关键字,以及程序执行的时间。

0

这段代码的输出越来越线程1的混合和thread0

package oopd; 
/** 
* 
* @author mani deepak 
*/ 
public class Oopd { 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) 
{ 
    // TODO code application logic here 
    Deepak d,d1; 
    d=new Deepak(); 
    d1=new Deepak(); 
    Thread t,t1; 
    t=new Thread(d); 
    t1=new Thread(d1); 
    t.start(); 
    t1.start(); 
} 
} 

class Deepak implements Runnable 
{ 
@Override 
public synchronized void run() 
{ 
    String s=Thread.currentThread().getName(); 
    for(int i=0;i<10;i++) 
    { 
     try 
     { 
     Thread.sleep(100); 
     } 
     catch(Exception e) 
     { 

     } 
     System.out.println(s+" "+i); 
    } 
} 
}