如何正确设置标志以使Java中的其他线程挂起?

如何正确设置标志以使Java中的其他线程挂起?,java,multithreading,synchronization,semaphore,Java,Multithreading,Synchronization,Semaphore,我正在学习java中的多线程,我得到了一个如下的问题 10个线程运行同一段代码,然后它们将定期进行测试。因此,当一个线程正在运行测试时,它将设置一个标志来挂起其他工作线程。然后,测试需要等待所有当前工作线程完成其工作。测试完成后,其他线程可以继续 现在,我的结构如下: //this is in run(), so every thread will run the below code //shared variables between threads. //int count=0; //b

我正在学习java中的多线程,我得到了一个如下的问题

10个线程运行同一段代码,然后它们将定期进行测试。因此,当一个线程正在运行测试时,它将设置一个标志来挂起其他工作线程。然后,测试需要等待所有当前工作线程完成其工作。测试完成后,其他线程可以继续

现在,我的结构如下:

//this is in run(), so every thread will run the below code
//shared variables between threads. 
//int count=0;
//boolean[] ifworking = new boolean[10]; initially set all to false
//boolean flag = false;
//int numtest = 0;

public void work(){
   int id = (int)Thread.currentThread().getId(); //get current thread id
   ifworking[id] = true;                         //indicate this thread is working
   while(true){
       if(!flag && numtest == 0){
       //do the work
       ifworking[id] = false;                    //indicate this thread is done
       break;
       }
   }
   if(++count%10 == 0) dotest();
}

public void dotest(){
  flag = true;                                  //shows a thread wants do test
  numtest++;                                    //count how many threads doing test
  while(true){
    int ifcantest = 0;
    for(int i=0;i<10;i++){
      if(!ifworking[i]) ifcantest++;
    }
    if(ifcantest == 10){
    //do the test code 
    numtest--;
    flag = false;
    break;
    }
  }
}
//这在run()中,因此每个线程都将运行以下代码
//线程之间共享变量。
//整数计数=0;
//布尔值[]如果工作=新布尔值[10];最初将all设置为false
//布尔标志=假;
//int numtest=0;
公共工程(){
int id=(int)Thread.currentThread().getId();//获取当前线程id
ifworking[id]=true;//指示此线程正在工作
while(true){
如果(!flag&&numtest==0){
//做这项工作
ifworking[id]=false;//指示此线程已完成
打破
}
}
如果(++计数%10==0)dotest();
}
公共空间dotest(){
flag=true;//显示要执行测试的线程
numtest++;//计算进行测试的线程数
while(true){
int-ifcantest=0;

对于(int i=0;i您需要一个读写锁。这样,一些被认为是读任务(在您的案例中工作)的任务可以并行执行,但至少有一个被认为是写任务(在您的案例中测试)的任务不能与其他任务并行运行


您可以在java中借助一个工具轻松地实现这一点。

您可以在具有线程执行的功能的对象上使用synchronize。否则,您可以定义自己的锁。

我刚刚找到了一个解决方案。我为此添加了一个信号量。代码如下所示:

   Private semaphore flag = new semaphore(10);//create a semaphore which contain 10 permits

   public void work(){
       flag.acquire();                        //acquire one permit
       //do the work
       flag.release();                        //release the permit
   }
   if(++count%10 == 0) dotest();
}

public void dotest(){                              
  while(true){
      if(flag.tryAcquire(10)) break;         //try acquire all permits. If true, all
                                             //the work threads will be blocked;
    }
    //do the test code 
    flag.release(10);                        //when test finish, release all permits,
                                             //then all blocking threads can resume.  
  }
}

此方法允许工作线程同时运行,当任何线程要测试时,它将等待所有其他线程完成工作。然后它可以阻止所有要工作的线程。

是否希望一次只在一个线程上运行
work()
?@AmanArora否,我希望这10个线程在work()上运行同时。然后,如果有一些线程在work()上完成,并且它们想要执行测试,它们必须等待其他线程完成它们的工作并挂起它们,然后它们可以同时执行test()。其他线程可以继续,直到测试完成。您希望所有线程首先完成
work()
当所有线程都完成了工作后,所有线程都应该启动
doTest()
?我理解你的意思了吗?@AmanArora是的,可能不是所有线程都想启动doTest(),有些线程会启动doTest。然后当线程完成doTest(),所有线程都会恢复,它们会重新运行工作()。是的,这可能对我有用。但如果我想让它更高效,它可能会是一个多编写器和多读取器的情况。同步只允许一个线程执行此任务,但实际上我需要它们同时工作。一旦线程移出同步块,其中一个被阻止的线程将访问该块。根据您的描述您可以使用类似R/W锁的功能。为什么您自己实现它?我已经告诉过您JDK中有一个,以及如何在您的案例中使用它。