为什么两个输出有所不同?

时间:2017-01-19 07:48:57

标签: java multithreading

public class EvenOddWithTwoThreads **extends Thread**
{
private volatile int count = 1;
private volatile boolean flag = false;
@Override
public void run() {
    while(count <=10){
        synchronized (this) {
            while(flag){
                flag= false;
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() +count);
            count= count+1;
            flag = true;

            notify();
        }
    }
}

public static void main(String[] args) {

    EvenOddWithTwoThreads ins = new EvenOddWithTwoThreads();
    **Thread t1 = new Thread(ins, "Odd Thread");**
    **Thread t2 = new Thread(ins,"Even Thread");**

    t1.start();
    t2.start();

    }
}

输出:

  

奇数线程1

     

奇数线程2

     

Odd Thread3

     

甚至是Thread4

     

奇数线程5

     

甚至是Thread6

     

Odd Thread7

     

甚至是Thread8

     

Odd Thread9

     

甚至是Thread10

public class EvenOddWithTwoThreads **implements Runnable**{

private volatile int count = 1;
private volatile boolean flag = false;


@Override
public void run() {
    while(count <=10){
        synchronized (this) {
            while(flag){
                flag= false;
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() +count);
            count= count+1;
            flag = true;

            notify();
        }
    }
}

public static void main(String[] args) {

    EvenOddWithTwoThreads ins = new EvenOddWithTwoThreads();
    Thread t1 = new Thread(ins, "Odd Thread");
    Thread t2 = new Thread(ins,"Even Thread");

    t1.start();
    t2.start();

    }
}
  

输出:

     

奇数线程1

     

Even Thread2

     

Odd Thread3

     

甚至是Thread4

     

奇数线程5

     

甚至是Thread6

     

Odd Thread7

     

甚至是Thread8

     

Odd Thread9

     

甚至是Thread10

1 个答案:

答案 0 :(得分:3)

扩展Thread或实施Runnable并不会改变代码的行为,但一般情况下,Runnable使用synchronization会更好地解释flag 3}}。 您展示的两个软件同样有问题,第二个软件正在回答正确的答案(我尝试在我的机器上运行它们并返回正确的答案)。

那么,发生了什么?在开始时,两个线程都处于 RUNNABLE 状态,因此两者都可以获取内部锁(使用fl.getPath().substring(0, fl.getPath().length()-3)原语)。在你的情况下,Odd Thread首先获得它,所以Even Threads进入 BLOCKED 状态。奇数线程打印他的号码并通知(在这种情况下没有人)。在循环结束时,它释放内部锁并再次启动循环。现在Even Thread不再被锁阻塞,因此两个线程都可以尝试再次获取内部锁:这称为 Race Condition ,这意味着输出依赖于两个线程的时间被执行。

在第一种情况下,Even Thread更快并获得锁定,但由于"BatchNorm"现在为真,它进入 WAITING 状态,释放Odd Thread用于打印的锁定&#34;奇数线程2&#34;并通知处于 BLOCKED 状态的Even Thread(有关详细信息,请参阅here)。在循环结束时奇数线程释放锁定,我们再次处于两个线程都可以获得锁定的情况:在最坏的情况下,偶数线程总是先进入并保持陷入while循环,等待奇数线程完成所有工作。