簡體   English   中英

如何使兩個線程等待並相互通知

[英]How to make two threads wait and notify each other

我必須創建兩個Threads,它們必須以2秒的間隔從隊列中輪詢和對象。

然后,第一個Thread輪詢和對象等待並通知第二個輪詢從其隊列中輪詢對象。

我讀了所有關於等待和通知的內容,但沒有任何關系。

任何sugestions?

第一個帖子:

public class SouthThread extends Thread {

private Queue<Car> q = new LinkedList<Car>();

public void CreateQueue() {

    Scanner input = new Scanner(System.in);

    for (int i = 0; i < 2; i++) {
        Car c = new Car();
        System.out.println("Enter registration number: ");
        String regNum = input.nextLine();
        c.setRegNum(regNum);
        q.offer(c);
    }
}

public int getQueueSize() {
    return q.size();
}

@Override
public void run() {
    while (q.size() != 0)
        try {
            while (q.size() != 0) {
                synchronized (this) {
                    System.out.print("The car with registration number: ");
                    System.out.print(q.poll().getRegNum());
                    System.out
                            .println(" have passed the bridge from the south side.");
                    this.wait(2000);
                    notify();

                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
}

}

第二個帖子:

public class NorthThread extends Thread {
private Queue<Car> q = new LinkedList<Car>();

public void CreateQueue() {

    Scanner input = new Scanner(System.in);

    for (int i = 0; i < 2; i++) {
        Car c = new Car();
        System.out.println("Enter registration number: ");
        String regNum = input.nextLine();
        c.setRegNum(regNum);
        q.offer(c);
    }
}

public int getQueueSize() {
    return q.size();
}

@Override
public void run() {
    try {
        while (q.size() != 0) {
            synchronized (this) {
                System.out.print("The car with registration number: ");
                System.out.print(q.poll().getRegNum());
                System.out
                        .println(" have passed the bridge from the north side.");
                this.wait(2000);
                notify();
            }
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

}

主線程:

public class Main {

public static void main(String[] args) throws Exception {
    // TODO Auto-generated method stub

    SouthThread tSouthThread = new SouthThread();
    NorthThread tNorthThread = new NorthThread();

    tSouthThread.CreateQueue();
    tNorthThread.CreateQueue();

    System.out.println(tSouthThread.getQueueSize());

    tSouthThread.start();
    tNorthThread.start();


}

}

看起來你基本上想要實現的是一個系統,它在兩個獨立單元之間交替控制,這樣每個單元都有一些時間來處理,然后是兩秒鍾的等待時間(反之亦然)。

有兩種主要方法可以實現此目的:

  1. 使用中央控制
  2. 擁有自主通信代理

第一種方法更容易一些。 在這里,您有一個中央“主”組件,負責協調誰獲得處理時間並實現等待時間。 對於這種方法,兩個獨立單元甚至不必是線程:

public class South {
    private Queue<Car> q = new LinkedList<Car>();

    public void CreateQueue() { ... }

    public void poll() {
        System.out.print("The car with registration number: ");
        System.out.print(q.poll().getRegNum());
        System.out.println(" have passed the bridge from the South side.");
    }
}

public class North {
    private Queue<Car> q = new LinkedList<Car>();

    public void CreateQueue() { ... }

    public void poll() {
        System.out.print("The car with registration number: ");
        System.out.print(q.poll().getRegNum());
        System.out.println(" have passed the bridge from the North side.");
    }
}

// This is the "master" class
public class Main {
    public static void main(String[] args) {
        South south = new South();
        North north = new North();

        south.CreateQueue();
        north.CreateQueue();

        boolean done = false;
        while (!done) {
            try {
                Thread.sleep(2000);
            } (catch InterruptedException) { /* TODO */ }

            north.poll();

            try {
                Thread.sleep(2000);
            } (catch InterruptedException) { /* TODO */ }

            south.poll();
        }
    }
}

請注意,North和South不會從Thread繼承,即它們只是普通的舊對象。 (但是,如果你的程序更復雜並且North / South只是它的一部分,你可能想讓Main(!)成為一個單獨的線程並將上面的while循環放在線程的run方法中,以便其余的該程序可以同時運行。)

在第二種方法中,您沒有這樣的中央控制組件,但是North和South都在它們自己的單獨線程中運行。 然后,這要求他們通過彼此通信來協調誰被允許處理。

public class SouthThread extends Thread {
    protected Queue<Car> q = new LinkedList<Car>();
    protected North north;

    public void CreateQueue() { ... }
    public void poll() { ... }

    public void run() {
        boolean done = false;
        while (!done) {
            // wait two seconds
            try {
                Thread.sleep(2000);
            } (catch InterruptedException) { /* TODO */ }

            // process one element from the queue
            poll();

            // notify the other thread
            synchronized (north) {
                north.notifyAll();
            }

            // wait until the other thread notifies this one
            try {
                synchronized (this) {
                    wait();
                }
            } (catch InterruptedException) { /* TODO */ }
        }
    }
}

public class NorthThread extends Thread {
    protected Queue<Car> q = new LinkedList<Car>();
    protected South south;

    public void CreateQueue() { ... }
    public void poll() { ... }

    public void run() {
        boolean done = false;
        while (!done) {
            // wait two seconds
            try {
                Thread.sleep(2000);
            } (catch InterruptedException) { /* TODO */ }

            // process one element from the queue
            poll();

            // notify the other thread
            synchronized (south) {
                south.notifyAll();
            }

            // wait until the other thread notifies this one
            try {
                synchronized (this) {
                    wait();
                }
            } (catch InterruptedException) { /* TODO */ }
        }
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        SouthThread tSouthThread = new SouthThread();
        NorthThread tNorthThread = new NorthThread();

        tSouthThread.north = tNorthThread;
        tNorthThread.south = tSouthThread;

        tSouthThread.CreateQueue();
        tNorthThread.CreateQueue();

        tSouthThread.start();
        tNorthThread.start();    
    }
}

更一般的說法:由於北方和南方似乎基本相同,因此可能不需要在兩個單獨的類中實現它們。 相反,只有一個實現所需功能的類並將其實例化兩次就足夠了:

// We can combine the functionality of North and South 
// in a single class
public class NorthSouth {
    public void CreateQueue() { ... }
    public void poll() { ... }

    // etc.
}

public class Main {
    public static void main(String[] args) {
        NorthSouth north = new NorthSouth();
        NorthSouth south = new NorthSouth();

        north.CreateQueue();
        south.CreateQueue();

        // etc.
    }
}

waitnotify必須引用相同的鎖:當你調用object.wait(2000) ,你所說的是“我要在這里等待2000毫秒,或者直到別人調用object.notify() ,其中object是指對我說

我仍然不完全理解你想要實現的目標,但如果你只是想要同時執行的兩個線程:

  1. 做一點事
  2. 等2秒
  3. GOTO 1

那么你根本不需要wait / notify,你可以使用Thread.sleep()或者可能是兩個java.util.Timer實例。

但同樣,我不確定我是否理解正確。 :-(

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM