cregithar 2020-11-25 19:58 采纳率: 78.9%
浏览 13
已采纳

java线程问题。。

在学习线程时遇到一个问题  
创建了一个类实现Runnable接口   

public class testRun implements Runnable{
    //线程停止标志位
    private volatile boolean cancelled = false;
    
    public void run(){
        int i = 1;
        
        //线程没停止时一直输出这句话
        while(!cancelled){
            System.out.println(i);
            i++;
        }
        
        System.out.println("线程结束后总该说点什么...");
    }
    
    //提供一个public的停止方法
    public void cancell(){
        System.err.println("线程结束");
        cancelled = true;
    }

}

测试类
 

//测试
public class test {
    
    public static void main(String[] args) {
        testRun run = new testRun();
        Thread t = new Thread(run);
        t.start();
        
        //这个是调用停止方法,这里不用就先放着先
    //  run.cancell();
    }

}

结果很奇怪,输出数字,但数字不是从1开始的,而是从很大的数开始的,并且每次的初始数都不一样,如图



第一个问题:为什么会出现这种情况?


接下来我尝试改一下run方法 
然后便发现在run方法的循环中加一个Thread.sleep()可以解决这个问题,不太懂。看代码

//修改后
public class testRun implements Runnable{
    //线程停止标志位
    private volatile boolean cancelled = false;
    
    public void run(){
        int i = 1;
        
        while(!cancelled){
            //没停止时一直输出这句话
            System.out.println(i);
            i++;
            
            //在循环里加入Thread.sleep
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            
        }
        
        System.out.println("线程结束后总该说点什么...");
    }
    
    //提供一个public的停止方法
    public void cancell(){
        System.err.println("线程结束");
        cancelled = true;
    }

}


 

问题二:为什么加入Thread.sleep()可以解决这个问题?

 

发现sleep可以解决这个问题后,我试了试Thread.sleep(0),发现不行。。。


public class testRun implements Runnable{
    //线程停止标志位
    private volatile boolean cancelled = false;
    
    public void run(){
        int i = 1;
        
        while(!cancelled){
            //没停止时一直输出这句话
            System.out.println(i);
            i++;
            
            //sleep(0)不行,和没加一样
            try {
                Thread.sleep(0);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        System.out.println("好吧我是傻瓜....");
    }
    
    //提供一个public的停止方法
    public void cancell(){
        System.err.println("线程结束");
        cancelled = true;
    }

}


问题三:为什么加入Thread.sleep(0)没有效果?

  • 写回答

2条回答 默认 最新

  • g5zhu5896 2020-11-26 10:44
    关注

    1.你可以认真看下,虽然不是从1开始,但是那边打印不是按顺序的,有可能 前面打印一个224123 下一个打印的是 4,我猜应该是打印到控制台是异步执行,然后打第一次循环打印1还没执行的时候,循环已经执行了20000万次,所以同时有 20000万次 打印要执行,打印顺序就不一定是 1开始了

    2.加了Thread.sleep(1000)可以是因为循环在第一次的时候 会睡眠一秒钟,这个时候不会执行第二次循环,这这一秒钟已经足够把第一次循环的1打印到控制台了

    3.Tthrea.sleep(0)几乎等于没睡眠,只是放弃当前的CPU占用

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?