同步问题

发布于 2024-12-03 05:02:49 字数 558 浏览 0 评论 0原文

  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
谁能解释一下吗?

  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());
      }
  }

The above code gives me output 8-1 9-1 8-2 9-2
But as the function is synchronized it should give output 8-1 8-2 9-1 9-2 or 9-1 9-2 8-1 8-2
Can anyone explain please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

故事和酒 2024-12-10 05:02:49

方法上的“同步”会同步该方法对特定对象的所有访问。

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

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

'synchronized' on a method synchronizes all accesses of that method on a particular object.

So if you have 1 PingPong object no 2 threads will simultaneously enter its hit method, but with 2 objects one thread can enter the hit method of one of the objects while another thread runs the hit object of the other.

This makes sense because you usually use synchronized to ensure undisturbed access to stuff local to the current object. If your object represents some external entity to which threads sometimes need undisturbed access, make your object a singleton.

自此以后,行同陌路 2024-12-10 05:02:49

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

 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 的单个实例,hit() 上的 synchronized 修饰符将防止一个线程中断另一个线程,您的输出将是 X-1 X-2 Y-1 Y-2 或反之亦然。

To get the behaviour you want, try making the following change:

 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());
      }
  }

With only a single instance of PingPong, the synchronized modifier on hit() will prevent one thread from interrupting the other, and your output will be either X-1 X-2 Y-1 Y-2 or visa-versa.

只为一人 2024-12-10 05:02:49

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

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

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

As per http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

First, it is not possible for two invocations of synchronized methods
on the same object to interleave.

So since you have two PingPong objects the synchronized keyword does not work as you expected.

梦里寻她 2024-12-10 05:02:49

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

此外,它还同步对象实例。作为两个实例,根本不存在同步。

Nope .. synchronized simply mean that a specific method will not be executed by two threads at the same time, but if you have two threads working they can call that method in any order anyway. Simply, they will not access at the same time.

Moreover, it synchronizes on the object instances. Being two instances, there is no synchronization at all.

水溶 2024-12-10 05:02:49

您没有锁定或解锁标志。所以他们会同时运行。

T1->run()->hit(); for循环
T2->run()->hit(); for循环

You have no lock or unlock flags. so they will both run at the same time.

T1->run()->hit(); forloop
T2->run()->hit(); forloop

锦欢 2024-12-10 05:02:49

将您的代码更改为

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());
  }   }

Change your code to

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());
  }   }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文