繁体   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