Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步问题 公共类乒乓球实现可运行{ 同步无效命中(长n){ 对于(int i=1;irun()->hit();forloop T2->run()->hit();前环_Java_Multithreading_Synchronization - Fatal编程技术网

Java 同步问题 公共类乒乓球实现可运行{ 同步无效命中(长n){ 对于(int i=1;irun()->hit();forloop T2->run()->hit();前环

Java 同步问题 公共类乒乓球实现可运行{ 同步无效命中(长n){ 对于(int i=1;irun()->hit();forloop T2->run()->hit();前环,java,multithreading,synchronization,Java,Multithreading,Synchronization,上面的代码给出了输出8-19-18-29-2 但是,当函数同步时,它应该给出输出8-18-29-19-2或9-19-28-18-2 有人能解释一下吗?一个方法上的“同步”将同步该方法对特定对象的所有访问 因此,如果你有一个PingPong对象,没有两个线程会同时进入它的hit方法,但是对于两个对象,一个线程可以进入其中一个对象的hit方法,而另一个线程运行另一个对象的hit对象 这是有意义的,因为您通常使用synchronized来确保不受干扰地访问当前对象的本地内容。如果您的对象表示线程有时需

上面的代码给出了输出8-19-18-29-2
但是,当函数同步时,它应该给出输出8-18-29-19-2或9-19-28-18-2

有人能解释一下吗?

一个方法上的“同步”将同步该方法对特定对象的所有访问

因此,如果你有一个
PingPong
对象,没有两个线程会同时进入它的
hit
方法,但是对于两个对象,一个线程可以进入其中一个对象的
hit
方法,而另一个线程运行另一个对象的
hit
对象


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

您没有锁定或解锁标志。因此,它们将同时运行

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

依照

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


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

否。。synchronized仅仅意味着一个特定的方法不会由两个线程同时执行,但是如果有两个线程在工作,那么它们可以以任何顺序调用该方法。简单地说,他们不会同时访问


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

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

  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());
      }
  }
公共类乒乓球实现可运行{
同步无效命中(长n){
对于(int i=1;i<3;i++)
系统输出打印(n+“-”+i+”);
}
公共静态void main(字符串[]args){
乒乓球p=新乒乓球();
新线程(p.start();
新线程(p.start();
}
公开募捐{
hit(Thread.currentThread().getId());
}
}
由于只有一个乒乓球实例,
hit()
上的
synchronized
修饰符将防止一个线程中断另一个线程,您的输出将是
X-1x-2y-1y-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) {
          PingPong p = new PingPong();
          new Thread(p).start();
          new Thread(p).start();
      }
      public void run() {
          hit(Thread.currentThread().getId());
      }
  }
公共类PingPong2实现可运行{
私有静态对象obj=新对象();
虚空命中(长n){
同步(obj)
{
对于(int i=1;i<3;i++)
系统输出打印(n+“-”+i+”);
}
}
公共静态void main(字符串[]args){
新线程(新乒乓球2()).start();
新线程(新乒乓球2()).start();
}
公开募捐{
hit(Thread.currentThread().getId());
}   }

@Mark——阻止第二个线程运行直到第一个线程运行的东西finished@Neal这就是OP希望通过
synchronized
实现的。如果他只有一个
PingPong
@Android的实例,或者你可以通过使
hit
成为一个静态方法来修复它,那么这将是可行的。在这种情况下,
synchronize
PingPong.class
上进行同步,而不是在两个不同的实例上进行同步。@tota当然可以,但这听起来像是非常糟糕的设计。无论如何,你需要一些对象来表示当前游戏状态,所以在上面同步似乎更好
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());
  }   }