[英]Print 1-1000 with two threads (even and odd) from the same class
所以我的任務是這樣的:
實例化同一類的兩個對象
提供構造函數參數,以將線程指定為偶數,將另一個指定為奇數。
一個接一個地啟動兩個線程
奇數線程打印從0到1000的奇數
偶數線程打印從0到1000的偶數
但是,它們應該保持同步,打印件應為1,2,3,4 .....
每行一個數字
但是我似乎無法正確釋放鎖。 我試過閱讀一些類似的問題,但它們都使用多個類。 我究竟做錯了什么?
編輯:我的主要班級正在這樣做-
NumberPrinter oddPrinter = new NumberPrinter("odd");
NumberPrinter evenPrinter = new NumberPrinter("even");
oddPrinter.start();
evenPrinter.start();
我的輸出是-奇數:1偶數:2 ...
public class NumberPrinter extends Thread {
private String name;
private int starterInt;
private boolean toggle;
public NumberPrinter(String name) {
super.setName(name);
this.name=name;
if(name.equals("odd")) {
starterInt=1;
toggle = true;
}
else if(name.equals("even")) {
starterInt=2;
toggle = false;
}
}
@Override
public synchronized void run() {
int localInt = starterInt;
boolean localToggle = toggle;
if(name.equals("odd")) {
while(localInt<1000) {
while(localToggle == false)
try {
wait();
}catch(InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println(name+": "+localInt);
localInt +=2;
localToggle = false;
notify();
}
}
else {
while(localInt<1000) {
while(localToggle == true)
try {
wait();
}catch(InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println(name+": "+localInt);
localInt +=2;
localToggle = true;
notify();
}
}
}
}
這里的關鍵問題是兩個線程無法相互協調。 當您有一個局部變量(在這種情況下為localToggle
)時,方法外的任何對象都無法觀察或更改其值。
但是,如果您與兩個線程共享一個對象,則其狀態可以更改,並且如果使用正確,則兩個線程都可以看到這些狀態更改。
你會看到實例共享對象是AtomicInteger
,但是當你用synchronized
, wait()
和notify()
你不需要內置到原子包裝的額外開銷的並發性。
這是一個簡單的輪廓:
class Main {
public static main(String... args) {
Main state = new Main();
new Thread(new Counter(state, false)).start();
new Thread(new Counter(state, true)).start();
}
int counter;
private static class Counter implements Runnable {
private final Main state;
private final boolean even;
Counter(Main state, boolean even) {
this.state = state;
this.even = even;
}
@Override
public void run() {
synchronized(state) {
/* Here, use wait and notify to read and update state.counter
* appropriately according to the "even" flag.
*/
}
}
}
}
我不清楚自己是否使用wait()
和notify()
是分配的一部分,但此大綱的替代方法是使用BlockingQueue
類的東西在兩個線程之間來回傳遞令牌。 (容易出錯的)狀態監視將內置到隊列中,從而清理代碼並減少出錯的可能性。
我終於使它以符合我的作業要求的標准的方式工作。 謝謝大家的意見。 我將答案留給可能需要的人。
public class Demo {
public static void main(String[] args) {
NumberPrinter oddPrinter = new NumberPrinter("odd");
NumberPrinter evenPrinter = new NumberPrinter("even");
oddPrinter.start();
evenPrinter.start();
System.out.println("Calling thread Done");
}
public class NumberPrinter extends Thread {
private int max = 1000;
static Object lock = new Object();
String name;
int remainder;
static int startNumber=1;
public NumberPrinter(String name) {
this.name = name;
if(name.equals("even")) {
remainder=0;
}else {
remainder=1;
}
}
@Override
public void run() {
while(startNumber<max) {
synchronized(lock) {
while(startNumber%2 !=remainder) {
try {
lock.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+": "+startNumber);
startNumber++;
lock.notifyAll();
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.