0

最近我开始研究多线程,我有一个问题,也许更有经验的人可以提供帮助。我的程序创建了两个并行线程,每个线程都打印从 0 到 19 的计数(实现 Runnable 接口的 NumbersPrinter 类)。

class NumbersPrinter implements Runnable {
  private Mediator mediator;
  private String name;
  private int makeActionOnCount;
  
  public NumbersPrinter(Mediator mediator, String name, int makeActionOnCount) {
    this.mediator = mediator;
    this.name = name;
    this.makeActionOnCount = makeActionOnCount;
  }   
  
  
  @Override
  public void run() {
    
    for(int i = 0; i<20; i++){
      
      try {
        synchronized(this.mediator) {
          if(this.mediator.actionInProgress.get()) {
           System.out.println(name + " waits");
           wait();
          }
        }
        System.out.println(this.name + " says " + i);     
        Thread.sleep(500);
        if(i == makeActionOnCount) {
          synchronized(this.mediator) {
            System.out.println(this.name + " asks Mediator to perform action...");
            this.mediator.performAction();
            this.mediator.notify();
          }
        }
        
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    
    
  }
}

当其中一个线程达到某个数量(在 makeActionOnCount 变量中定义)时,它开始执行某个操作以停止执行第二个计数器。该动作持续 5 秒,之后两个计数器继续计数。计数器通过 Mediator 类的实例互连,performAcyion() 方法也属于 Mediator 类的实例。

import java.util.concurrent.atomic.AtomicBoolean;

class Mediator {
  public AtomicBoolean actionInProgress = new AtomicBoolean(false);
  
  public Mediator() {
    
  }
  
  public void performAction() throws InterruptedException {
    
    actionInProgress.set(true); 
    System.out.println("Action is being performed");
    Thread.sleep(5000);   
    System.out.println("Action has been performed");
    actionInProgress.set(false);        
    
  }
}

这是主类:

class Main {
  
 
  public static void main(String[] args) throws InterruptedException{   
    
    
    Mediator mediator = new Mediator();
    
    NumbersPrinter data = new NumbersPrinter(mediator, "Data", 10);
    NumbersPrinter lore = new NumbersPrinter(mediator, "Lore", 5);
    
    Thread oneThread = new Thread(data);
    Thread twoThread = new Thread(lore);    
    
    System.out.println("Program started");
    
    oneThread.start();
    twoThread.start();
    oneThread.join();
    twoThread.join();
    
    System.out.println("Program ended");
  }

现在编写程序的方式 - 工作正常,但我不太明白我应该在第一个同步块中写什么,因为如果你从中删除所有内容,程序仍然可以工作,因为计数器不执行performAction() 方法停止,因为计数器无法访问 Mediator 对象的监视器,因为它正忙于并行计数器。AtomicBoolean 变量并检查它也没有任何意义。换句话说,我可能根本不使用 wait() 和 notify() 构造,以及 AtomicBoolean 变量的值,而只是使用空的同步块在每次新迭代时检查对 Mediator 对象的监视器的访问。但我听说空的同步块是一种不好的做法。

我正在寻求有关如何重写程序以正确使用同步块以及 wait() 和 notify() 方法的帮助。也许我在错误的对象上同步?你会如何解决类似的问题?提前致谢

4

0 回答 0