簡體   English   中英

使用相同類別的兩個線程(偶數和奇數)打印1-1000

[英]Print 1-1000 with two threads (even and odd) from the same class

所以我的任務是這樣的:

  1. 實例化同一類的兩個對象

  2. 提供構造函數參數,以將線程指定為偶數,將另一個指定為奇數。

  3. 一個接一個地啟動兩個線程

  4. 奇數線程打印從0到1000的奇數

  5. 偶數線程打印從0到1000的偶數

  6. 但是,它們應該保持同步,打印件應為1,2,3,4 .....

  7. 每行一個數字

但是我似乎無法正確釋放鎖。 我試過閱讀一些類似的問題,但它們都使用多個類。 我究竟做錯了什么?

編輯:我的主要班級正在這樣做-

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 ,但是當你用synchronizedwait()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.

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