簡體   English   中英

使用2個線程打印奇數和偶數?

[英]Printing Odd and Even number using 2 threads?

我已經嘗試過此代碼。 但是在打印0之后,它什么也不會打印。 由於某些鎖定,它正在阻塞。

public class EvenOdd implements Runnable {
    private Object o = new Object();
    private volatile int i = 0;

    public void run() {
        try {
            System.out.println();
            if ( Thread.currentThread().getName().equals( "Even")) {
                printEven();
            } else {
                printOdd();
            }
        } catch ( Exception ee) {
            ee.printStackTrace();
        }
    }

    private void printEven() throws InterruptedException {
        while ( true) {
            synchronized ( o) {
                while ( this.i % 2 == 0) {
                    o.wait();
                }
                System.out.println( Thread.currentThread().getName() + i);
                i++;
                o.notify();
            }
        }
    }

    private void printOdd() throws InterruptedException {
        while ( true) {
            synchronized ( o) {
                while ( this.i % 2 != 0) {
                    o.wait();
                }
                System.out.println( Thread.currentThread().getName() + i);
                i++;
                o.notify();
            }
        }
    }
}

我的TestClass:

EvenOdd x = new EvenOdd();
        new Thread(x,"Even").start();
        new Thread(x,"Odd").start();

我哪里錯了? 謝謝。

PS:我知道這類問題已經問過很多次了,但我想自己嘗試一下。

我的猜測是你是。

  • 使用一個Runnable,但是兩者都認為它們是偶數,即它們都看到第一個值0
  • printEven必須等待一個奇數廣告printOdd必須等待一個偶數

編輯:運行代碼后,OP修復了代碼,它會打印

0
1

如預期的那樣。 有時可能會隨機打印0和0,因為第一次檢查奇數/偶數不同步。

這是一個簡單的僵局:

線程1等待有人通知鎖。 線程2等待有人通知相同的鎖。

由於沒有人去過o.notify(); , 什么都沒發生。

當兩個線程都啟動時, i為0,因此都先調用printEven() 現在,當發生這種情況時,兩個線程將在下一輪調用printOdd()

基本概念是當一個線程正在運行時,另一個線程必須等待。 一旦線程打印了值,它就必須等到另一個線程打印出來。 這是通過使用等待/通知機制來實現的。

當奇數線程完成打印值時,它將通知等待線程(偶數線程),並且偶數線程准備就緒,可以運行,但將等待奇數線程釋放鎖定。 現在,奇數線程調用在更衣室對象上等待,以便它釋放鎖並進入等待狀態。 在這一點上,唯一等待鎖對象鎖定的線程是偶數線程並且它正在運行。 此過程將繼續進行。

public class Test {
    public static void main(String[] args) {
        Object locker = new Object();
        Thread t1 = new Thread(new OddWorker(locker));
        Thread t2 = new Thread(new EvenWorker(locker));
        t1.start();
        t2.start();

    }
}

class OddWorker implements Runnable {
    private Object locker;
    private int number = 1, count = 1;

    OddWorker(Object locker) {
        this.locker = locker;
    }

    @Override
    public void run() {
        synchronized (locker){
            do {
                try {
                    System.out.println(Thread.currentThread().getName() + ": " + number);
                    number += 2;
                    locker.notify();
                    locker.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } while(++count < 11);
            locker.notify();
        }
    }
}

class EvenWorker implements Runnable {
    private Object locker;
    private int number = 2, count = 1;

    EvenWorker(Object locker) {
        this.locker = locker;
    }

    @Override
    public void run() {
        synchronized (locker){
            do {
                try {
                    System.out.println(Thread.currentThread().getName() + ": " + number);
                    number += 2;
                    locker.notify();
                    locker.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } while(++count < 11);
        }
    }
}

暫無
暫無

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

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