簡體   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