简体   繁体   中英

Threads Waiting in Line Queue, Java

I'm In a sticky situation. I know this is almost as far as i can get for now, but what i want to do is actually to make an array of thread (or many thread) and accommodate number of threads in queue in the line, so for example i can accommodate 3 thread at a time, i make the first 3 thread run, then make the other wait, when there is free like for example the 1 is free or terminated the other one can start running.

also i want to make sure if the thread can run or not if the thread that is running is the same as the other thread's gender.

    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();
        }

        }

        }

For now what i can make is accommodate or make 1 thread run at a time.

(Yes this is a Machine bathroom Problem)

My real question is. if i Edit the function run() in myThread() that has a wait() or just plain put a System.out.println(getName() + " is Using"); And how will the thread know in their run() function that other thread is running.

 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<<<<
 }

Or should i just implement that outside? or put the Waiting outside? Also i'm really new in Threading so i haven't really explored with Sleep and Interrupt yet.

You can do this without wait .

Here is an example:

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");
            }
        }
    }
}

Since only one thread can synchronize on an object at a time it means that only one thread of a given gender can run at a time. This creates sequential execution of all threads of a given gender.

And here is an example of using this kind of thread.

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

I would just use two single thread executors obtained via Executors.newSingleThreadExecutor(); , one for each gender, and then submit the task to the appropriate executor. Simple and done.

And if you only have one bathroom, then only one executor is needed. For example:

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");
    }
}

... so for example i can accommodate 3 thread at a time, i make the first 3 thread run, then make the other wait, when there is free like for example the 1 is free or terminated the other one can start running.

This can be achieved using a Executor with a fixed Thread Pool.

 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(); ...})
 }

Since this aa batroom the ques are seperate an there will be fixed number of toilets:

 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 */ ...})
 }

To implement the queue you can use one of the BlockingQueue implementations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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