2016-10-01 10 views
1

Я в липкой ситуации. Я знаю, что это почти так, как я могу получить сейчас, но то, что я хочу сделать, это на самом деле создать массив потоков (или многих потоков) и разместить количество потоков в очереди в строке, так что, например, я могу разместить 3 потока за раз, я делаю первые три потока, а затем заставляю остальных ждать, когда есть свободные, например, 1 свободный или завершенный, другой может начать работать.Threads Waiting in Line Queue, Java

также я хочу убедиться, что поток может работать или нет, если поток, который работает, такой же, как пол другого потока.

Thread myThreads[] = new Thread[LN.GetLine().length()]; 
    int l=LN.GetLine().length(); 
    for (int j = 0; j < LN.GetLine().length(); j++) { 
    String Name = CR.Gender(LN.GetLine().charAt(j)) + j; 
    myThreads[j] = new Thread(new MyThread(Name,LN)); 
    myThreads[j].setPriority(l); 
    System.out.println(myThreads[j].toString()); 
    l--; 
    } 
    for(int b=0;b<LN.GetLine().length();b++){ 
     myThreads[b].start(); 
     synchronized(myThreads[b]){ 
      try{ 
       myThreads[b].wait();  
     }catch(InterruptedException e){ 
      e.printStackTrace(); 
     } 

     } 

     } 

На данный момент то, что я могу сделать, это разместить или сделать 1 поток за один раз.

(Да это машина ванной проблема)

Мой реальный вопрос. if i Отредактируйте функцию run() в myThread(), которая имеет wait() или просто выложила System.out.println(getName() + " is Using"); И как нить знает в своем run(), что работает другой поток.

public class MyThread extends Thread { 
public MyThread(String id) { 
super(id); 
} 
public void run(){ 
System.out.println(getName() + " is Using"); 
>>>Put wait if other thread running<<<< 
>>>If can use or not if same gender<<<< 
} 

Или я должен просто реализовать это снаружи? или поставить Ожидание снаружи? Также я действительно новичок в Threading, поэтому я еще не изучил спящий режим и прерывание.

+1

Вызов 'wait()' в потоке необычен, и в этом случае он не имеет никакого эффекта. – Titus

+0

Да, я знаю, что к этому времени я попробовал ... Во всяком случае, я не могу убить/остановить поток, потому что это будет означать, что они не могут использовать, может быть, если я смогу заставить весь поток ждать и оставаться ждать. пока я не возобновит их, если они смогут использовать. – HerlDerp

+0

Рассмотрите возможность использования пула фиксированных потоков ExecutorService (в вашем случае размер пула будет 3). Этот метод не потребует создания потоков, которые ждут (расточительство ресурсов). ref: https://docs.oracle.com/javase/7/docs/api/index.html?java/util/concurrent/ExecutorService.html – mangotang

ответ

0

Вы можете сделать это без wait.

Вот пример:

public class MyThread extends Thread { 
    static final Object gender1Lock = new Object(); 
    static final Object gender2Lock = new Object(); 
    int gender; 
    public MyThread(String id, int gender) { 
     super(id); 
     this.gender = gender; 
    } 
    public void run(){ 
     System.out.println(getName() + " is waiting"); 
     if(gender == 1){ 
      synchronized(gender1Lock){ // ocupy gender 1 
       System.out.println(getName() + " is Using"); 
      } 
     }else if(gender == 2){ 
      synchronized(gender1Lock){ // ocupy gender 2 
       System.out.println(getName() + " is Using"); 
      } 
     } 
    } 
} 

Поскольку только один поток может synchronize на объекте в то время, это означает, что только один поток данного пола может работать одновременно. Это создает последовательное выполнение всех потоков определенного пола.

И вот пример использования такого рода ниток.

for(int i = 0; i < 20; i++){ 
    new MyThread("Person " + i, (i%2 == 0) ? 1 : 2).start(); 
} 
+0

Возможно, я смущен, но не будет ли gender1Lock и gender2Lock статичным в этой ситуации? И разве мы не хотим внедрять Runnable, а не расширять Thread? А как насчет использования какого-то типа стека или ... –

+1

сервис исполнителя? –

+0

@HovercraftFullOfEels Да, я только что осознал, что сам («статичная вещь»). – Titus

0

Я просто хотел бы использовать две отдельные исполнители нити, полученные с помощью Executors.newSingleThreadExecutor();, по одному для каждого пола, а затем представить задачу соответствующему исполнителю. Просто и сделано.

И если у вас только одна ванная комната, нужен только один исполнитель. Например:

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class GetInLine { 
    public static void main(String[] args) { 
     List<MyRunnable> myRunnables = new ArrayList<>(); 
     myRunnables.add(new MyRunnable("Bob", false)); 
     myRunnables.add(new MyRunnable("Jill", true)); 
     myRunnables.add(new MyRunnable("Frank", false)); 
     myRunnables.add(new MyRunnable("Amy", true)); 
     myRunnables.add(new MyRunnable("Pete", false)); 
     myRunnables.add(new MyRunnable("Diane", true));   

     ExecutorService myExecutor = Executors.newSingleThreadExecutor(); 
     for (MyRunnable myRunnable : myRunnables) { 
      myExecutor.submit(myRunnable); 
     } 

     myExecutor.shutdown(); 
    } 
} 

public class MyRunnable implements Runnable { 
    private static final int MIN_SLEEP_TIME = 500; 
    private static final int MAX_SLEEP_TIME = 2000; 
    private static final int FEMALE_SLEEP_BONUS = 500; 
    private Random random = new Random(); 
    private String name; 
    private boolean female; 

    public MyRunnable(String name, boolean female) { 
     this.name = name; 
     this.female = female; 
    } 

    public String getName() { 
     return name; 
    } 

    public boolean isFemale() { 
     return female; 
    } 

    @Override 
    public void run() { 
     System.out.println(name + " is using"); 
     try { 
      long sleepTime = MIN_SLEEP_TIME + random.nextInt(MAX_SLEEP_TIME - MIN_SLEEP_TIME); 
      if (female) { 
       sleepTime += FEMALE_SLEEP_BONUS; 
      } 
      Thread.sleep(sleepTime); 
     } catch (InterruptedException e) {} 
     System.out.println(name + " is done"); 
    } 
} 
0

... так, например, я могу разместить 3 нить в то время, я сделать первый запуск 3 нити, а затем сделайте другой ждать, когда свободен, как, например, 1 свободен или завершен, другой может начать работать.

Это может быть достигнуто с помощью Исполнителя с фиксированным пулом потоков.

ExecutorService m = Executors.newFixedThreadPool(3) 
ExecutorService f = Executors.newFixedThreadPool(3) 
for(;;) { 
    Object o = new Object(); 
    m.execute(() -> {...; o.wait(); /* You know notify was called on o at this point hence f run clause is running or has just run */ ...}) 
    f.execute(() -> {...; o.notify(); ...}) 
} 

Поскольку это в batroom в Ques является самостоятельным будет фиксированное количество туалетов:

ExecutorService m = Executors.newFixedThreadPool(3) 
ExecutorService f = Executors.newFixedThreadPool(3) 
for(;;) { 
    Person male = getNextMale(); 
    m.execute(() -> {...; /* do something with male */ ...}) 

    Person female = getNextFemale(); 
    f.execute(() -> {...; /* do something with female */ ...}) 
} 

Для реализации очереди вы можете использовать один из BlockingQueue реализаций.

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

  • Нет связанных вопросов^_^