繁体   English   中英

等待队列中的线程,Java

[英]Threads Waiting in Line Queue, Java

我处在一个棘手的局面。 我知道这几乎是我现在可以得到的,但我想要做的实际上是创建一个线程数组(或许多线程)并容纳行中队列中的线程数,所以例如我可以容纳一次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个线程。

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

我真正的问题是。 如果我在myThread()中编辑函数run()有一个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。

你可以不用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();
}

我只想使用通过Executors.newSingleThreadExecutor();获得的两个单线程执行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");
    }
}

...所以例如我一次可以容纳3个线程,我让前3个线程运行,然后让另一个等待,当有空闲时,例如1是空闲或终止,另一个可以开始运行。

这可以使用具有固定线程池的Executor来实现。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM