Java 线程等待通知

发布于 2024-09-28 07:28:55 字数 1258 浏览 7 评论 0原文

我有 3 个线程(A、B、C),但我无法让它们按照我想要的方式工作。 所有这 3 个线程共享对同一对象 - K 的引用。 我想做的是启动所有 3 个线程,然后在线程 A 到达某个状态时的某个时间点,暂停线程 B 和 C,直到 A 执行某个方法 work() ,当工作完成时,恢复B 和 C。

现在我的代码中有什么: 线程 A 引用了 B 和 C。 B和C有一个方法pause(){synchronized(K){k.wait; }} 当 A 到达某个状态时,我调用 FROM A 的 run() 方法:B.pause()、C.pause()。 现在我期待的是线程 B 和 C 将等待,直到有人发出 k.notifyAll(),但线程 A 停止了。这在java中正常吗?

代码:

class A implements Runnable {
   private K k;
   private B b;
   private C c;

   void run() {
      while(something) {
         //do something
         b.pause();
         c.pause();
          // !!! here this thread will freeze and doSomething2 wont get executed.
          // what i want is to pause B, C, doSomething2 to get executed and then resume B and C
         //do something2 
         synchronized(k) {
           k.notifyAll();
         }
      }
   }
}
class B implements Runnable {
   private K k;


   void run() {
      while(something) {
         //dome something
         }
      }
   }
   public pause() {
       synchronized(k) { k.wait();}
   }
}
class C implements Runnable {
   private K k;


   void run() {
      while(something) {
         //dome something
         }
      }
   }
   public pause() {
       synchronized(k) { k.wait();}
   }
}

I have 3 threads (A, B, C) that i just can't make them work how i want them to.
ALL these 3 threads share a reference to the same object - K.
What i'm trying to do, is to start all 3 up, then at some point in time when thread A arrives in a certain state, pause threads B and C, until A executes some method work() and when work finishes, resume B and C.

Now what i have in my code:
Thread A has reference to both B and C.
B and C have a method pause() { synchronized(K) { k.wait; }}
When A arrives in that certain state, i call FROM A's run() method: B.pause(), C.pause().
Now what i'm expecting is that Threads B and C will waiT until someone makes a: k.notifyAll(), BUT instead Thread A stops. Is this normal in java ?

Code:

class A implements Runnable {
   private K k;
   private B b;
   private C c;

   void run() {
      while(something) {
         //do something
         b.pause();
         c.pause();
          // !!! here this thread will freeze and doSomething2 wont get executed.
          // what i want is to pause B, C, doSomething2 to get executed and then resume B and C
         //do something2 
         synchronized(k) {
           k.notifyAll();
         }
      }
   }
}
class B implements Runnable {
   private K k;


   void run() {
      while(something) {
         //dome something
         }
      }
   }
   public pause() {
       synchronized(k) { k.wait();}
   }
}
class C implements Runnable {
   private K k;


   void run() {
      while(something) {
         //dome something
         }
      }
   }
   public pause() {
       synchronized(k) { k.wait();}
   }
}

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

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

发布评论

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

评论(7

や三分注定 2024-10-05 07:28:55

您可以使用 CylcicBarrier 来实现这。

CyclicBarrier barrier = new CyclicBarrier();

public void run() {
    new Thread(new A(barrier)).start();
    new Thread(new B(barrier)).start();

    barrier.await();  // Waits until all threads have called await()

    // Do something
}

public void A implements Runnable {
    private CyclicBarrier barrier;

    public A(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    public void run() {
        barrier.await();
        // Do something.
    }
}

public void B implements Runnable {
    private CyclicBarrier barrier;

    public B(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    public void run() {
        barrier.await();
        // Do something.
    }
}

You can use a CylcicBarrier to implement this.

CyclicBarrier barrier = new CyclicBarrier();

public void run() {
    new Thread(new A(barrier)).start();
    new Thread(new B(barrier)).start();

    barrier.await();  // Waits until all threads have called await()

    // Do something
}

public void A implements Runnable {
    private CyclicBarrier barrier;

    public A(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    public void run() {
        barrier.await();
        // Do something.
    }
}

public void B implements Runnable {
    private CyclicBarrier barrier;

    public B(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    public void run() {
        barrier.await();
        // Do something.
    }
}
蹲在坟头点根烟 2024-10-05 07:28:55

当你调用 B.pause() 时,它是在本地线程中执行的,而不是在你调用 B 的 run 方法的线程中执行的。
Thread 类中有一些已弃用的方法可以执行此操作,但它们很危险,请参见此处:
http://download.oracle.com/javase/1.5 .0/docs/guide/misc/threadPrimitiveDeprecation.html

When you call B.pause(), it is executed in the local thread, not in the thread where you called run method of B.
There are some deprecated methods on the Thread class to do that but they are dangerous, see here:
http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

聚集的泪 2024-10-05 07:28:55

您确定调用 b.pause() 但声明 B.sleep() 吗?

很高兴看到线程构造/启动代码。

Are you sure that you call b.pause() but declare B.sleep() ?

Would be nice to see threads construction/start code.

桃气十足 2024-10-05 07:28:55

您知道您正在使用 3 个不同的对象(监视器)Ak、Bk、Ck 吗?

因此,当 B“暂停”时,它会在自己的监视器 (Bk) 上同步,无论如何,该监视器应该是空闲的。
您的线程不会以任何方式“通信”。

You know that you are using 3 diferent objects (monitors) A.k,B.k,C.k ?

So when B "paused" it synchronized on their own monitor (B.k) that should be free anyway.
Your threads do not "communicate" in any way.

十六岁半 2024-10-05 07:28:55

A.run() 中删除对 b.pause()c.pause() 的调用,并从它们自己的 run 方法中调用它们。

Remove the calls to b.pause() and c.pause() from A.run() and call them from their own run methods.

森林很绿却致人迷途 2024-10-05 07:28:55

除非我误解了你的作业,否则我认为你需要做的是学习如何中断线程。 B 和 C 是可中断线程,需要以这样的方式处理中断:在被告知可以之前它们不会恢复。它可能看起来像这样:

while(true)
{
   try
   {
      Thread.sleep(100);
      System.out.println("Thread is working normally...");
   }
   catch(InterruptedException e)
   {
      System.out.println("Thread has been interrupted, will wait till A is done...");
      try
      {
         synchronized(monitor)
         {
           monitor.wait();
         }
      }
      catch(InterruptedException e2)
      {
         // whatever...
      }
   }
}

因此,在自己的线程中运行的对象 A 将引用其他两个线程。对象 A 将有权访问共享监视器对象,其他两个线程中的可运行对象也可以访问该对象(我将其称为“监视器”)。当 A 中断其他线程时,它们的可运行对象将在监视器上调用 wait()。当 A 完成后,它将在监视器上调用 notifyAll()。注意,您也应该清除其他线程中的中断标志,但我将其留给您来解决 - 这很容易:)

Unless I am misunderstanding your homework assignment, what I think you need to do is learn how to interrupt a thread. B and C are interruptable threads that need to handle the interrupt in such a way that they will not resume until they have been told it is OK. It could look something like this:

while(true)
{
   try
   {
      Thread.sleep(100);
      System.out.println("Thread is working normally...");
   }
   catch(InterruptedException e)
   {
      System.out.println("Thread has been interrupted, will wait till A is done...");
      try
      {
         synchronized(monitor)
         {
           monitor.wait();
         }
      }
      catch(InterruptedException e2)
      {
         // whatever...
      }
   }
}

So object A running in its own thread will have references to two other threads. Object A will have access to a shared monitor object that the runnables in the two other threads also have access to (I called it monitor). When A interrupts the other threads their runnables will then call wait() on the monitor. When A is done it will call notifyAll() on the monitor. NOTE you should clear the interrupt flag in the other threads too, but I leave that to you to figure out - its easy :)

放我走吧 2024-10-05 07:28:55

我通常不会在这个细节上帮助你完成家庭作业,但我认为你无论如何都使用了错误的方法,所以我认为帮助你做一些你几乎肯定不应该做的事情并没有什么坏处:)

class A implements Runnable {
   private K k;
   private B b;
   private C c;

   void run() {
      while(something) {
         //do something
         b.pause();
         c.pause();
          // !!! here this thread will freeze and doSomething2 wont get executed.
          // what i want is to pause B, C, doSomething2 to get executed and then resume B and C
         //do something2 
         synchronized(k) {
           k.notifyAll();
         }
      }
   }
}
class B implements Runnable {
   private K k;
   volatile boolean isPaused = false;


   void run() {
      while(something) {
         if (isPaused) {
           synchronized(k) { k.wait();}
           isPaused = false;
         }
         //dome something
      }
   }
   public pause() {
     isPaused = true;
   }
}
class C implements Runnable {
   private K k;
   volatile boolean isPaused = false;


   void run() {
      while(something) {
        if (isPaused) {
          synchronized(k) {
            k.wait();
          }
          isPaused = false;
        }
        //dome something
      }
   }
   public pause() {
     isPaused = true;
   }
}

我猜你真正想做的是无条件地在 BC 中的 k 上调用 wait,然后始终在 A 中调用 notificationAll

I don't normally help with homework in this detail, but I think you are using the wrong approach anyway, so I don't see the harm in helping you do something you almost certainly shouldn't be doing :)

class A implements Runnable {
   private K k;
   private B b;
   private C c;

   void run() {
      while(something) {
         //do something
         b.pause();
         c.pause();
          // !!! here this thread will freeze and doSomething2 wont get executed.
          // what i want is to pause B, C, doSomething2 to get executed and then resume B and C
         //do something2 
         synchronized(k) {
           k.notifyAll();
         }
      }
   }
}
class B implements Runnable {
   private K k;
   volatile boolean isPaused = false;


   void run() {
      while(something) {
         if (isPaused) {
           synchronized(k) { k.wait();}
           isPaused = false;
         }
         //dome something
      }
   }
   public pause() {
     isPaused = true;
   }
}
class C implements Runnable {
   private K k;
   volatile boolean isPaused = false;


   void run() {
      while(something) {
        if (isPaused) {
          synchronized(k) {
            k.wait();
          }
          isPaused = false;
        }
        //dome something
      }
   }
   public pause() {
     isPaused = true;
   }
}

I'm guessing that what you really want to do though is unconditionally call wait in on k in B and C and then always call notifyAll in A

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