2013-04-22 2 views
0

Im делает многопоточное приложение, в котором пользователь добавляет по 1 ингредиент за один раз, чтобы сделать фруктовый салат. Существует максимальное количество фруктов, которые можно положить в миску.Проблемы с запуском нескольких потоков

Код компилируется и запускается, но проблема в том, что он работает только с одним потоком (Apple). Клубника имеет тот же самый поток thread.sleep (1000), что и яблоко. Я попробовал сменить сон клубнику на другое время сна, но это не устранило проблему.

Apple.java

public class Apple implements Runnable 
{ 
    private Ingredients ingredient; 

    public Apple(Ingredients ingredient) 
    { 
     this.ingredient = ingredient; 
    } 

    public void run() 
    { 
     while(true) 
     { 
      try 
      { 
       Thread.sleep(1000); 
       ingredient.setApple(6); 
      } 
      catch (InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

Ingredients.java

public interface Ingredients 
{ 
    public void setApple(int max) throws InterruptedException; 
    public void setStrawberry(int max) throws InterruptedException; 
} 

FruitSalad.java

public class FruitSalad implements Ingredients 
{ 
    private int apple = 0; 
    private int strawberry = 0; 

    public synchronized void setApple(int max) throws InterruptedException 
    { 
     if(apple == max) 
      System.out.println("Max number of apples."); 
     else 
     { 
      apple++; 
      System.out.println("There is a total of " + apple + " in the bowl."); 
     } 
    } 
    //strawberry 
} 

Main.java

public class Main 
{ 
     public static void main(String[] args) 
     { 
      Ingredients ingredient = new FruitSalad(); 

      new Apple(ingredient).run(); 
      new Strawberry(ingredient).run(); 
     } 
} 

Выход:

  • В общей сложности в яблоке содержится 1 яблоко.
  • ....
  • В общей сложности в яблоке содержится 6 яблоко.
  • Максимальное количество яблок.
+1

Это потому, что вы не можете запускать их в отдельных потоках .. вы работаете как в текущем потоке, что приведет к их последовательному выполнению. – mre

+0

Как запустить их в отдельных потоках? – user2273278

+0

Кроме того, я бы порекомендовал, чтобы фруктолад ссылался на ингредиенты, а не наоборот. Это стандартная практика; многие к одному лучше, чем одни. –

ответ

2

При вызове метода .run() на Runnable непосредственно в другом потоке, вы просто добавить, что «нить» в одном стеке (т.е. он работает в одном потоке).

Вы должны вместо этого обернуть Runnable в новый поток и использовать .start() для выполнения потока.

Apple apple = new Apple(ingredient); 
Thread t = new Thread(apple); 
t.start(); 


Strawberry strawberry = new Strawberry(ingredient); 
Thread t2 = new Thread(strawberry); 
t2.start(); 

Вы по-прежнему вызываете метод run() напрямую. Вместо этого вы должны вызвать метод start(), который вызывает run() косвенно в новом потоке. См. Править.

+0

Вместо редактирования боевых действий, в будущем я рекомендую просто откат вашего редактирования :) –

+0

Это не сработало. его все еще работает только яблоко – user2273278

+0

Ну, да, потому что он только создает яблоко; Затем вам нужно будет создать Strawberry и вызвать 'start()' на нем таким же образом. – drewmoore

0

Попробуйте сделать это вместо:

Thread t1 = new Thread(new Apple(ingredient)); 
t1.start; 

Thread t2 = new Thread(new Strawberry(ingredient)); 
t2.start(); 
0

Пусть ваши классы продлить Thread:

public class Apple extends Thread 
public class Strawberry extends Thread 

Затем вы можете начать эти темы:

Apple apple = new Apple(ingredient); 
Strawberry strawberry = new Strawberry(ingredient); 

apple.start(); 
strawberry.start(); 

Вы должны позвонить присоединиться на обоих потоков дождаться их до окончания:

apple.join(); 
strawberry.join(); 
+1

+1 для продления Thread. –

+0

Да, продолжение Thread отлично, если вам не нужно расширять другой класс ... – drewmoore

Смежные вопросы