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 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题