簡體   English   中英

線程未同時運行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM