-1

为什么有时我会得到输出:

患者 4 访问医生办公室。

患者 2 访问医生办公室。

患者 1 访问医生办公室。

当我期望输出按递增顺序排列时,即患者 1,然后是患者 2 或 3,然后是患者 4 或 5。即,我无法理解它是如何在从初始 for 循环到 0 之前看到打印 4主类是设置患者编号的,我立即启动线程。

这是我的代码:

public static void main(String[] args)
{
    NUM_P = 5;//TEMPORARILY HARD CODE, WILL TAKE ARG FROM COMMANDLINE IN THE FUTURE
    NUM_A = 2;
    Patient[] myPatients = new Patient[NUM_P];
    for (int i = 0; i < NUM_P; i++)
    {
         Patient patient = new Patient();
         patient.setPatientNumber(i);
         myPatients[i] = patient;
         myPatients[i].start();
    }
}

在病人课上,

public void run() 
{
    attendParty();
    visitDoctor();
}

public void visitDoctor()
{
    System.out.println("Patient-"+(this.getPatientNumber())+" visits doctor office.");
}

public void attendParty() throws InterruptedException
{
    Random randomGen = new Random();
    int val = randomGen.nextInt(101);
    if (val < 20)
    {
        interrupt();
        //NO NEED TO CREATE A PATIENT THREAD, THE PATIENT IS NOT SICK HEHE
    }
    else
    {
        this.setSickness(true);//He is sick
    }
}
4

3 回答 3

2

启动线程后,该线程何时获得周期完全取决于 VM。不能保证它们会按照它们被 start()ed 的顺序运行。

于 2013-08-03T16:57:32.187 回答
1

当线程并行运行时,执行顺序通常是不确定的。所以你的代码输出是完全正常的——你几乎同时启动所有线程,而且大部分时间它们是并行运行的。

于 2013-08-03T16:57:03.273 回答
0

线程处理是由 vm 而不是你的代码完成的。这意味着您的系统决定何时允许线程运行以及允许运行多长时间,除非您命令线程等待、睡眠或屈服。还可以选择声明首选项。这些开关不会等到线程到达分号,并且可以(大多数情况下)在字节码级别的操作之间发生。通常不建议不要从代码中干扰线程处理,除非您出于计时目的绝对需要它。当两个线程有​​可能访问和更改同一资源时,您仍然应该始终记住同步,以便在操作/方法/等中间切换线程。会弄乱两个线程的结果。

于 2013-08-03T17:06:57.707 回答