如何正确设置标志以导致其他线程在Java中挂起?

时间:2013-12-03 04:14:44

标签: 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;
//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;
    }
  }
}

显然这段代码不是那么有效,它有死锁,有时当一个线程正在测试时,其他线程将并行工作,那么测试就不准确了。 那么有人可以帮我修改代码吗?我需要10个线程同时完成工作,如果任何线程完成工作,它将等待其他人完成然后测试。此外,10个线程可以同时进行测试,一旦没有线程测试,线程恢复工作。 这个run()将继续运行该进程。

3 个答案:

答案 0 :(得分:0)

您需要一个读写锁。使用pattern某些任务被视为读取任务(在您的情况下工作)可以并行执行但至少有一个任务被认为是编写(在您的情况下测试)不能与其他任务并行运行

您可以在this class的帮助下轻松地在java中执行此操作。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

   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.  
  }
}

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