2016-03-29 4 views
0

runnableインターフェイスを実装することにより、クラスDisplayPhilosopherを作成しました。 私のプロジェクトの他のクラスに多くのスレッドを作成しました。 メソッドwait()(またはsleep())を使用してこれらのスレッドを一時停止し、ボタンを押したときに目を覚まして続行する方法(notify())すべてのヘルプは大幅appreaciatedされるだろうrunnableインターフェイスを実装して作成したスレッドをスリープ()または待機()するにはどうすればよいですか?

public class Display extends JPanel implements Runnable { 

    Image bg; 
    Image s0, s1, s2, s3, s4; 
    Image plate[] = new Image[5]; 
    Toolkit t; 
    Image state1, state2; 
    Font font; 
    Chopstick chopstick; 
    Philosopher philosopher; 

    boolean isRunning = false; 

    public Display() { 
     t = Toolkit.getDefaultToolkit(); 
     font = new Font("Tahoma", Font.PLAIN, 20); 
     bg = t.getImage("image//BG.png"); 
     s0 = t.getImage("image//ts0.png"); 
     s1 = t.getImage("image//ts1.png"); 
     s2 = t.getImage("image//ts2.png"); 
     s3 = t.getImage("image//ts3.png"); 
     s4 = t.getImage("image//ts4.png"); 
     state1 = t.getImage("image//eating.png"); 
     state2 = t.getImage("image//thinking.png"); 
     plate[0] = t.getImage("image//p0.png"); 
     plate[1] = t.getImage("image//p2.png"); 
     plate[2] = t.getImage("image//p3.png"); 
     plate[3] = t.getImage("image//p4.png"); 
     plate[4] = t.getImage("image//p5.png"); 

     chopstick = new Chopstick(); 
     philosopher = new Philosopher(); 

    } 

    public void run() { 
     while (!isRunning) { 
      repaint(); 

      try { 
       Thread.sleep(50); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public boolean getStop() { 
     return isRunning; 
    } 

    public void setStop(boolean stop) { 
     isRunning = stop; 
    } 

    public void paint(Graphics g) { 
     super.paint(g); 
     // this.setBackground(Color.white); 
     g.drawImage(bg, 0, 0, 800, 600, null); 
     drawP(g); 
     drawP0(g); 
     drawP1(g); 
     drawP2(g); 
     drawP3(g); 
     drawP4(g); 
     draw0(g); 
     draw1(g); 
     draw2(g); 
     draw3(g); 
     draw4(g); 
     drawS0(g); 
     drawS1(g); 
     drawS2(g); 
     drawS3(g); 
     drawS4(g); 
    } 

    public void draw0(Graphics g) { 
    } 

    public void draw1(Graphics g) { 
    } 

    public void draw2(Graphics g) { 
    } 

    public void draw3(Graphics g) { 
    } 

    public void draw4(Graphics g) { 
    } 

    public void drawP0(Graphics g) { 
    } 

    public void drawP1(Graphics g) { 
    } 

    public void drawP2(Graphics g) { 
    } 

    public void drawP3(Graphics g) { 
    } 

    public void drawP4(Graphics g) { 
    } 

    public void drawP(Graphics g) { 
    } 

    // 
    public void drawS0(Graphics g) { 
    } 

    public void drawS1(Graphics g) { 
    } 

    public void drawS2(Graphics g) { 
    } 

    public void drawS3(Graphics g) { 
    } 

    public void drawS4(Graphics g) { 
    } 

    public void drawQuote(Graphics g) { 
     if (philosopher.getQuote(0) == 1) { 

     } 
     if (philosopher.getQuote(0) == 2) { 

     } 
     if (philosopher.getQuote(0) == 3) { 

     } 
    } 
} 


    public class App { 

    JButton btPause, btStart; 
    JPanel panelButton; 
    JFrame f1; 
    Chopstick chopstick[]; 
    Philosopher philosophers[]; 

    final String TITLE = "Dining Pholosophers Simulator"; 
    final ImageIcon ICON_START = new ImageIcon("image/run.png"); 
    final ImageIcon ICON_PAUSE = new ImageIcon("image/play.png"); 
    final ImageIcon ICON_RESUME = new ImageIcon("image/resume.png"); 

    boolean isRunning = false; 

    public App() { 

     f1 = new JFrame(); 
     //f1.setLayout(null); 
     f1.setTitle(TITLE); 
     f1.setSize(1120, 680); 
     f1.setVisible(true); 
     f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f1.setLocationRelativeTo(null); 
     f1.setResizable(false); 

     // Khởi tạo 5 cây đũa 
     initializePos(); 
     // Khởi tạo 5 luồng (Triết gia) 
     initializePhilosopher(); 
     Display obj = new Display(); 
     obj.setBounds(0, 0, 1040, 600); 

     // Luồng chính Frame cửa sổ chính 
     Thread t1 = new Thread(obj); 
     // t1.start(); 
     // Chạy 5 luồng triết gia 
     Thread p1 = new Thread(philosophers[0]); 
     // p1.start(); 
     Thread p2 = new Thread(philosophers[1]); 
     // p2.start(); 
     Thread p3 = new Thread(philosophers[2]); 
     // p3.start(); 
     Thread p4 = new Thread(philosophers[3]); 
     // p4.start(); 
     Thread p5 = new Thread(philosophers[4]); 
     // p5.start(); 
     // f1.add(obj0); 
     f1.add(obj); 

     //btStart = new JButton("Start...", new ImageIcon("image/pause16.png")); 
     btStart = new JButton("Run", ICON_START); 
     btPause = new JButton("Pause", ICON_PAUSE); 
     btPause.setEnabled(false); 

     // Chạy các tiến trình 
     btStart.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       t1.start(); 
       p1.start(); 
       p2.start(); 
       p3.start(); 
       p4.start(); 
       p5.start(); 
       isRunning = true; 
       btStart.setEnabled(false); 
       btPause.setEnabled(true); 
      } 
     }); 

     // Đóng băng các tiến trình đang chạy 
     btPause.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       // Nếu đóng băng 
       if (isRunning) { 
        isRunning = false; 
        // Thay đổi trên giao diện 
        btPause.setText("Resume"); 
        btPause.setIcon(ICON_RESUME); 

        // I want to call the method to pause those threads here 

       } else { 
        isRunning = true; 
        btPause.setText("Pause"); 
        btPause.setIcon(ICON_PAUSE); 

        // I want to call the method to continue threads here 
       } 
      } 
     }); 

     // f1.add(btStart, BorderLayout.SOUTH); 
     panelButton = new JPanel(); 
     panelButton.setLayout(new FlowLayout()); 
     panelButton.add(btStart); 
     panelButton.add(btPause); 
     f1.add(panelButton, BorderLayout.SOUTH); 
     f1.validate(); 

    } 

    public void initializePos() { 
     chopstick = new Chopstick[5]; 
     chopstick[0] = new Chopstick(0, 270, 330); 
     chopstick[1] = new Chopstick(1, 200, 200); 
     chopstick[2] = new Chopstick(2, 350, 120); 
     chopstick[3] = new Chopstick(3, 500, 210); 
     chopstick[4] = new Chopstick(4, 430, 330); 
    } 

    public void initializePhilosopher() { 
     philosophers = new Philosopher[5]; 
     philosophers[0] = new Philosopher(0, chopstick[0], chopstick[4]); 
     philosophers[1] = new Philosopher(1, chopstick[1], chopstick[0]); 
     philosophers[2] = new Philosopher(2, chopstick[2], chopstick[1]); 
     philosophers[3] = new Philosopher(3, chopstick[3], chopstick[2]); 
     philosophers[4] = new Philosopher(4, chopstick[4], chopstick[3]); 
    } 

    public static void main(String args[]) { 
     System.out.println("Simulator is ready, click Start...\n"); 
     new App(); 
    } 
} 

は、ここに私のコードです。

+0

スレッドがスリープしたり、待機したり、別のスレッドに対して何かを実行したりしないでください。スレッドは協力する必要があります。スレッドAがスレッドBが一時停止すべき理由を知っている場合、スレッドAはスレッドBにメッセージを送信し、スレッドBは一時停止する必要があります。 –

答えて

1

あなたはそれらのrun()方法で適切なポイントで待機してから再開することを通知する哲学者の言うことができる:

boolean waitRequested = false; 

void requestWait() { 
    waitRequested = true; 
} 

void resume() { 
    synchronized(this) { 
    notify(); 
    } 
}  

public void run() {  
    while(condition) { 
    try { 
     //check if the thread should wait first, if not let it do a full iteration of the loop 
     if(waitRequested) { 
     synchronized(this) { 
      wait(); 

      //resuming here so wait wouldn't be requested anymore 
      waitRequested = false; 
     } 
     } 

     //do whatever a philosopher does 
    } 
    catch(InterruptedException e) { 
     //handle exception 
    } 
    } 
} 

次にオブジェクトにrequestWait()resume()を呼び出します。 notify()を呼び出すことができますが、それを同期ブロックで囲む必要があります。notify()を呼び出すスレッドはモニタの現在の所有者ではない可能性が最も高いので、最も確実にIllegalMonitorStateExceptionが得られます。

関連する問題