同步问题

时间:2011-09-07 18:21:51

标签: java multithreading synchronization

  public class PingPong implements Runnable {
      synchronized void hit(long n) {
          for (int i = 1; i < 3; i++)
              System.out.print(n + "-" + i + " ");
      }
      public static void main(String[] args) {
          new Thread(new PingPong()).start();
          new Thread(new PingPong()).start();
      }
      public void run() {
          hit(Thread.currentThread().getId());
      }
  }

上面的代码给出了输出8-1 9-1 8-2 9-2
但是当功能同步时,它应该输出 8-1 8-2 9-1 9-2或9-1 9-2 8-1 8-2
有人可以解释一下吗?

6 个答案:

答案 0 :(得分:7)

方法上的

'synchronized'同步该方法对特定对象的所有访问。

因此,如果您有1个PingPong对象,则没有2个线程将同时进入其hit方法,但是对于2个对象,一个线程可以输入其中一个对象的hit方法,而另一个线程运行另一个的hit对象。

这是有道理的,因为您通常使用synchronized来确保不受干扰地访问当前对象的本地内容。如果您的对象代表线程有时需要不受干扰访问的某个外部实体,请将您的对象设为单个。

答案 1 :(得分:4)

要获得所需的行为,请尝试进行以下更改:

 public class PingPong implements Runnable {
      synchronized void hit(long n) {
          for (int i = 1; i < 3; i++)
              System.out.print(n + "-" + i + " ");
      }
      public static void main(String[] args) {
          PingPong p = new PingPong();
          new Thread(p).start();
          new Thread(p).start();
      }
      public void run() {
          hit(Thread.currentThread().getId());
      }
  }

只有PingPong的单个实例,synchronized上的hit()修饰符会阻止一个帖子中断另一个,并且您的输出将是X-1 X-2 Y-1 Y-2或签证-versa。

答案 2 :(得分:1)

根据http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

  

首先,两次调用同步方法是不可能的   在同一个交错的对象上。

因此,由于您有两个PingPong对象,synchronized关键字无法按预期工作。

答案 3 :(得分:1)

Nope .. synchronized只是意味着一个特定的方法不会同时由两个线程执行,但如果你有两个线程正在工作,他们无论如何都可以以任何顺序调用该方法。简单地说,他们不会同时访问。

此外,它在对象实例上同步。作为两个实例,根本没有同步。

答案 4 :(得分:0)

您没有锁定或解锁标志。所以他们都会在同一时间跑。

  

T1-&gt;运行() - &GT;命中(); for循环
  T2-&gt;运行() - &GT;命中(); for循环

答案 5 :(得分:0)

将您的代码更改为

public class PingPong2 implements Runnable {

private static Object obj = new Object();
    void hit(long n) {
     synchronized(obj)
     {
    for (int i = 1; i < 3; i++)
        System.out.print(n + "-" + i + " ");
     }
}
public static void main(String[] args) {
    new Thread(new PingPong2()).start();
    new Thread(new PingPong2()).start();
}
public void run() {
    hit(Thread.currentThread().getId());
  }   }