当前位置: 首页 > 知识库问答 >
问题:

如何从线程 1 等待,直到线程 2 发出通知

郭修平
2023-03-14

我是多线程的新手,当我阅读有关多线程的内容时,我想编写这个精美的多线程代码来执行以下操作。

我的柜台类如下。

class Counter {
  private int c = 0;

  public void increment() {
    System.out.println("increment value: "+c);
      c++;
  }

  public void decrement() {
      c--;
      System.out.println("decrement value: "+c);
  }

  public int value() {
      return c;
  }

}

这个计数器对象由两个线程共享。一旦线程启动,我需要做以下事情。我希望Thread2一直等到Thread1将Counter对象的计数加1。完成后,线程1通知线程2,然后线程1开始等待线程2将值递减1。然后,线程2启动并将值递减1,并再次通知线程1,然后线程2开始等待线程1。重复这个过程几次。

我怎样才能做到这一点。提前非常感谢。

我已经做到了以下几点。

public class ConcurrencyExample {

  private static Counter counter;
  private static DecrementCount t1;
  private static IncrementCount t2;

  public static void main(String[] args) {
    Counter counter = new Counter();
    Thread t1 = new Thread(new IncrementCount(counter));
    t1.start();

    Thread t2 = new Thread(new DecrementCount(counter));
    t2.start();

  }

}


public class DecrementCount implements Runnable {

  private static Counter counter;

  public DecrementCount(Counter counter) {
    this.counter = counter;
  }

  @Override
  public void run() {
    for (int i = 0; i < 1000; i++) {
      counter.decrement();     
      System.out.println("decreamented");
    }
  }

}


public class IncrementCount implements Runnable {

  private static Counter counter;

  public IncrementCount(Counter counter) {
    this.counter = counter;
  }

  @Override
  public void run() {
    for (int i = 0; i < 1000; i++) {
      counter.increment();
      System.out.println("Incremented");
    }

  }

}

共有3个答案

羊时铭
2023-03-14

- 首先,您的增量()递减()必须使用同步关键字以避免争用条件 请参阅此布莱恩规则

当我们编写刚刚被另一个线程读取的变量,或者读取最近由另一个线程写入的变量时,必须使用同步。访问字段数据的原子语句/方法也必须同步。

-它的JVM Thread Scheduler可以控制哪个线程将进入运行状态,它将在那里停留多长时间,以及工作完成后它将去哪里。

- 人们无法确定哪个线程将首先运行.....

-您还可以使用java.util中的SingleThreadExecutor。concurrent,完成一个任务后再进行第二个任务。

汝彭薄
2023-03-14

同步器使线程能够彼此等待。请参阅CountDownLatch和信号量。

请参见java.util.concurrent包中的同步器一节

寿亦
2023-03-14

查看信号量。您将需要两个,每个线程一个:内信号量dec 信号量。在递减计数中执行:

for (int i = 0; i < 1000; i++) {
  decSemaphore.acquire();
  counter.decrement();     
  System.out.println("decreamented");
  incSemaphore.release();
}

对称地实现< code>IncrementCount。对于< code>decSemaphore,incSemaphore的初始值应为< code>1和< code>0。

顺便说一句,您的计数器也需要同步(请参阅同步关键字和原子交互器)。

 类似资料:
  • 问题内容: 我正在为我的ubuntu服务器(针对我的多客户端匿名聊天程序)实现一种简单的线程池机制,并且需要使我的工作线程进入睡眠状态,直到需要执行一项工作(以函数指针和参数的形式) 。 我当前的系统即将关闭。我(工人线程正在)问经理是否有工作可用,以及是否有5毫秒没有睡眠。如果存在,请将作业添加到工作队列中并运行该函数。糟糕的循环浪费。 什么我 喜欢 做的是做一个简单的事件性的系统。我正在考虑有

  • 问题内容: 我正在用一个应用程序逻辑线程和一个数据库访问线程来制作Java应用程序。他们都坚持为应用程序和都需要的整个生命周期,以在同一时间运行(一个会谈到服务器,一个谈判给用户;当应用程序完全启动,我需要两个人工作)。 但是,在启动时,我需要确保最初应用线程等待直到数据库线程准备就绪(当前是通过轮询自定义方法确定的)。我不介意应用线程在数据库线程准备就绪之前是否阻塞。 看起来不是解决方案-db线

  • 问题内容: 在这里,我想每秒钟调用一次“ Log.d”和“ postInvalidate”。但是,当我从LogCat检查它时,似乎循环运行的速度比我希望的要快。为什么这个循环不等待1000ms? 以下是LogCat中的输出。因此,您可以看到它根本没有休眠1秒钟。我也使用了Thread.sleep(在您建议之后) 这是最新的代码。是布尔值,现在是事实。 输出是 问题答案: 您需要类的方法。 使发送此

  • 但这一个也不起作用。正确的答案是加入线程并删除2个睡眠: 我的问题是:为什么我的答案都不能被接受?我的实验室领导问,但他不能给我一个答案。在家里编写了测试代码,它似乎工作得很好。提前感谢您的帮助!

  • 我想做一个小练习来习惯等待/通知。我想做的是简单地启动一个线程,然后用等待让它进入睡眠状态,用通知唤醒它,多次。 我的代码是: 我希望这会是这样 相反,这样做: 所以。。。通知似乎没有唤醒打印机线程? 这不应该是一个死锁,因为通过等待,我释放了所有的锁,所以主服务器不应该有任何对打印机的锁,打印机应该能够唤醒并打印。 我做错了什么?

  • 问题内容: 我有以下情况: 为了运行算法,我必须运行多个线程,并且每个线程都会在死之前设置一个实例变量x。问题是这些线程不会立即返回: 我应该使用等待通知吗?还是我应该嵌入一个while循环并检查是否终止? 感谢大家! 问题答案: 创建一些共享存储来保存每个线程的值,或者如果足够的话,只存储总和。使用a 等待线程终止。每个线程完成后都会调用,您的方法将使用该方法来等待它们。 编辑: 这是我建议的方