首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线无睡眠

问线无睡眠
EN

Stack Overflow用户
提问于 2015-02-22 14:30:43
回答 3查看 1.1K关注 0票数 1

我使用线程非常新,我只是做了一个小程序来了解它是如何工作的。举个例子,一个做了素数练习的程序运行得很好,但是我发现如果我不使用use (),每次按run (不改变代码)时,数字的顺序就会改变。为什么会发生这种事?

代码语言:javascript
复制
    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之后的结果:

​

​

这是再次按下run后的结果:

​

​

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-22 14:41:33

发生这种情况有两个原因:

  1. 您的主要方法不是同步的。
  2. 即使同步了主方法,也要将ThreadDemo的不同实例传递给线程。在对象上获得锁。如果两个线程被传递给ThreadDemo的两个不同对象,每个线程将锁定自己的ThreadDemo实例,从而允许线程并行运行。

您需要对代码进行一些更改,以确保对两个线程都使用相同的ThreadDemo。

代码语言:javascript
复制
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();
    }
}

这会解决你的问题。

票数 0
EN

Stack Overflow用户

发布于 2015-02-22 14:42:55

发生这种情况的原因是线程并行运行。当您创建一堆线程时,这些线程都同时开始执行,这是一场竞赛,以查看哪些线程首先完成。这不是确定性的,有时线程会以不同的顺序结束。

睡眠可能改变的原因是,睡眠将使您首先创建的线程具有先机。

票数 1
EN

Stack Overflow用户

发布于 2015-02-22 15:08:09

Wikipedia将线程定义为:“在计算机科学中,执行线程是可由调度程序独立管理的程序指令的最小序列”。

调度器是在SO内核中运行并管理进程和线程执行的软件模块。调度程序使用时分复用(如多任务)算法,以确保所有线程和进程都能够执行。在Windows、Mac和Linux等SOs中,调度器的一个特点是CPU在不同的软件线程之间切换。正如维基百科中所述:“这种上下文切换通常发生得足够频繁,以至于用户认为线程或任务同时运行。”

基于这些考虑,我们可以解释您的软件行为。非实时操作系统(如windows和MAC OSx )和许多Linux发行版都使用不确定的调度算法,因此我们无法预测线程的执行顺序,因此很可能每次执行时都会得到与文本输出顺序不同的结果。

当您在线程执行之间使用睡眠时,所选择的时间量似乎足以使th1在th2启动之前完全执行。因此,输出按正确的顺序显示。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28658971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档