我刚学习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()将继续运行该进程。
答案 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.
}
}
此方法允许工作线程同时运行,并且当任何线程想要测试时,它将等待所有其他线程完成工作。然后它可以阻止所有想要工作的线程。