我是使用Threads的新手,我只是做了一个小程序来了解它是如何工作的。作为一个例子,做了一个素数练习,程序运行得很完美,但我发现如果我不使用sleep(),每次按下运行时数字的顺序都会改变(不改变代码) 。那么为什么会这样呢?
class Prime extends ThreadDemo implements Runnable
{
public void run()
{
for(int i=2;i<=20;i++)
{
if(prime(i))
{
System.out.printf ("Prime No.= %d \n",i);
}
}
}
}
class notPrime extends ThreadDemo implements Runnable
{
int number= 0;
public void run()
{
prime(number);
}
}
class ThreadDemo
{
public boolean prime(int start_value)
{
for(int i=2; i<start_value; i++)
{
if(start_value%i == 0)
{
System.err.printf ("No. Prime = %d \n", start_value);
return false;
}
}
return true;
}
public static void main(String args[])
{
Prime th1 = new Prime();
Thread childOne = new Thread(th1);
childOne.start();
notPrime th2 = new notPrime();
Thread childTwo = new Thread(th2);
childTwo.start();
}
}
这是我按下run后的结果:
这是按下再次运行后的结果:
答案 0 :(得分:1)
发生这种情况的原因是线程并行运行。当你创建一堆线程时,这些线程都会同时开始执行操作,并且看到哪些线程首先完成是一场竞赛。这不是确定性的,有时线程将以不同的顺序完成。
睡眠可能会改变这一点的原因是,睡眠会让你创建的主线先行开始。
答案 1 :(得分:0)
发生这种情况有两个原因:
您需要对代码进行一些更改,以确保线程使用相同的ThreadDemo。
class NotPrimeRunnable implements Runnable {
private ThreadDemo threadDemo;
int number = 0;
public NotPrimeRunnable(ThreadDemo threadDemo) {
this.threadDemo = threadDemo;
}
public void run() {
threadDemo.prime(number);
}
}
class PrimeRunnable implements Runnable {
private ThreadDemo threadDemo;
public PrimeRunnable(ThreadDemo threadDemo) {
this.threadDemo = threadDemo;
}
@Override
public void run() {
for (int i = 2; i <= 20; i++) {
if (threadDemo.prime(i)) {
System.out.printf("Prime No.= %d \n", i);
}
}
}
}
class ThreadDemo {
public synchronized boolean prime(int start_value) {
for (int i = 2; i < start_value; i++) {
if (start_value % i == 0) {
System.err.printf("No. Prime = %d \n", start_value);
return false;
}
}
return true;
}
public static void main(String args[]) {
ThreadDemo runnableTask = new ThreadDemo();
PrimeRunnable th1 = new PrimeRunnable(runnableTask);
Thread childOne = new Thread(th1);
childOne.start();
NotPrimeRunnable th2 = new NotPrimeRunnable(runnableTask);
Thread childTwo = new Thread(th2);
childTwo.start();
}
}
这将解决您的问题。
答案 2 :(得分:0)
维基百科将线程定义为:&#34;在计算机科学中,执行线程是可以由调度程序独立管理的最小程序指令序列&#34;。
调度程序是在SO内核中运行的软件模块,用于管理进程和线程执行。调度程序使用时分多路复用(如在多任务处理中)算法,以确保所有线程和进程都能够执行。在Windows,Mac OS和Linux等SO中,调度程序的特性之一是CPU在不同的软件线程之间切换。如维基百科中所述:&#34;此上下文切换通常经常发生,用户将线程或任务视为同时运行。&#34;
基于这些考虑因素,我们可以解释您的软件行为。非实时操作系统,如Windows和MAC OSx,以及许多Linux发行版都使用非确定性的调度算法,因此我们无法预测线程的执行顺序,那么每次执行时你很可能会获得关于文本输出顺序的不同结果。
当你在线程执行之间使用sleep时,似乎所选择的时间量足以在th2启动之前完全执行。因此输出以正确的顺序显示。