[英]Threads not running concurrently
我希望這不是重復的問題,但是我已經查看了其他問題的所有答案,但沒有一個讓我滿意。
我有一個解決了餐飲哲學家問題的程序,當我運行該程序時,線程會等到下一個完成后再運行另一個。 這將導致線程的輸出如下所示:
Philosopher 1 is EATING.
Philosopher 1 is THINKING.
Philosopher 5 is EATING.
Philosopher 5 is THINKING.
Philosopher 3 is EATING.
Philosopher 3 is THINKING.
... 等等。 預期的輸出沒有訂單。 線程應同時運行。 這是我的代碼,所有代碼都在這里,接口僅指定DINERS(5)和State的大小。_______是具有3個狀態的枚舉:State.HUNGRY,State.THINKING和State.EATING。
import java.lang.Runnable;
import java.util.concurrent.locks.*;
import java.util.Random;
import java.lang.Thread;
import java.util.concurrent.TimeUnit;
/**
* This class handles the Philosophers, I hope they are hungry.
*
* @version 4-20-15
*/
public class Diner implements Runnable, PhilosopherInterface {
/** The lock used to control Thread access */
private final ReentrantLock lock;
/** The state that the Philosopher is in (ex: Eating, Thinking etc.) */
private State current;
/** The random number used to generate time sleeping */
private Random timeGenerator;
/** The maximum time a thread can sleep */
private final int maxTimeToSleep = 5000;
/** The minimum time a thread can sleep (1ms) */
private final int minTimeToSleep = 1;
private int philNum;
private int philIndex;
private Condition[] condition;
private State[] states;
public Diner(ReentrantLock lock, int philNumber, Condition[] condition, State[] states)
philNum = philNumber;
philIndex = philNum - 1;
current = states[philNumber-1];
timeGenerator = new Random();
this.lock = lock;
this.condition = condition;
this.condition[philIndex] = lock.newCondition();
this.states = states;
states[philIndex] = State.THINKING;
}
@Override
public void takeChopsticks() {
states[philIndex] = State.HUNGRY;
lock.lock();
try{
int left = philIndex-1;
int right = philIndex+1;
if(philNum == DINERS) right = 0;
if(philNum == 1) left = DINERS - 1;
test(left, philIndex, right);
if(states[philIndex] != State.EATING) {
condition[philIndex].await();
}
}catch(InterruptedException e){}
}
@Override
public void replaceChopsticks() {
try{
states[philIndex] = State.THINKING;
int left = philIndex-1;
int right = philIndex+1;
if(philNum == DINERS) right = 0;
if(philNum == 1) left = DINERS - 1;
int leftOfLeft = left-1;
int rightOfRight = right+1;
if(left == 0) leftOfLeft = DINERS-1;
test(leftOfLeft, left, philIndex);
if(right == DINERS-1) rightOfRight = 0;
test(philIndex, right, rightOfRight);
}finally{ lock.unlock(); }
//states[philIndex] = State.THINKING;
//condition[left].signal();
//condition[right].signal();
}
public void think() {
System.out.println("Philosopher " + philNum + " is " + State.THINKING + ".");
int timeToSleep = timeGenerator.nextInt(maxTimeToSleep) + minTimeToSleep;
try {
Thread.sleep(500);
}catch(InterruptedException e) {}
}
public void eat() {
System.out.println("Philosopher " + philNum + " is " + State.EATING + ".");
int timeToSleep = timeGenerator.nextInt(maxTimeToSleep) + minTimeToSleep;
try {
Thread.sleep(500);
}catch(InterruptedException e){}
}
@Override
public void run() {
while(true) {
think();
takeChopsticks();
eat();
replaceChopsticks();
}
}
public State getState() {
return current;
}
private void test(int left, int current, int right) {
if(states[left] != State.EATING && states[current] == State.HUNGRY
&& states[right] != State.EATING) {
states[current] = State.EATING;
condition[current].signal();
}
}
}
為什么胎面不能同時運行? 謝謝您的幫助! 編輯:要運行它,有一個驅動程序是這樣的:
public class Lunch {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Thread[] diners = new Thread[PhilosopherInterface.DINERS];
Condition[] table = new Condition[PhilosopherInterface.DINERS];
State[] states = new State[PhilosopherInterface.DINERS];
for(int i=0; i<PhilosopherInterface.DINERS; i++) {
states[i] = State.THINKING;
}
for(int i=0; i<PhilosopherInterface.DINERS; i++) {
Diner diner = new Diner(lock, i+1, table, states);
diners[i] = new Thread(diner);
diners[i].start();
}
}
}
EDIT2:找出問題,在下面回答。
告訴線程等待並不強制它們同時工作。 如果一個線程在激活另一個線程之前需要遵循幾個步驟,則這些方法(步驟)應該同步。
我只在takeChopsticks()開頭鎖定了一次,並在replaceChopsticks()結束時解鎖了,迫使線程在解鎖之前執行所有操作。
我在takeChopsticks()和replaceChopsticks()的開始和結束時都使用了lock()和unlock()方法,從而使其可以同時運行。
嘗試使用ExecutorService 。 使用ExecutorService.submit(Runnable)
和ExecutorService.shutdown()
將等待所有Runnable
都終止並關閉ExecutorService
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.