等待队列中的线程,Java

时间:2016-10-01 14:20:02

标签: java multithreading wait sleep interrupt

我在一个棘手的情况下。我知道这几乎是我现在可以得到的,但我想要做的实际上是创建一个线程数组(或许多线程)并容纳行中队列中的线程数,所以例如我可以容纳一次3个线程,我让第3个线程运行,然后让另一个等待,当有空闲时,例如1是空闲或终止,另一个可以开始运行。

我还想确定线程是否可以运行,如果正在运行的线程与其他线程的性别相同。

    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个线程。

(是的,这是机器浴室问题)

我真正的问题是。如果我编辑run()myThread()的{​​{1}}中的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<<<<
 }

或者我应该在外面实施?或者把等待放在外面? 此外,我在线程中真的很新,所以我还没有真正探索过Sleep和Interrupt。

3 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分: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");
    }
}

答案 2 :(得分: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(); ...})
 }

由于这是一个酒吧,问题是分开的,将有固定数量的厕所:

 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实现。