[英]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.