sinat_32123569
about4y
采纳率0%
2017-01-20 02:52

多线程小白 一个简单问题

30
 public class Demo10 {
    public static void main(String[] args) {
        Thread10 t10 = new  Thread10();
        for(int i = 0;i<10000;i++) {
            Thread t = new Thread(t10);
            t.start();
        }
    }
}

class Thread10 implements Runnable {

    private static int count = 0;
    @Override
    public void run() {
        // TODO Auto-generated method stub
            System.out.println(count++);
    }
}

这样有没有可能会出现2个重复的数字??我运行了一下感觉没有,但是我觉得应该会有几率重复的吧?
求大神解释一下,最好讲的明白一点。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

9条回答

  • wuyupengwoaini wuyupengwoaini 4年前

    count++ 看上去好像是原子性的操作,但实际上在程序中最起码有三步 1:从内存把count读取到寄存器中 2:在寄存器上运算+1 3:把运算之后的结果
    存储到内存上。所以如果有两个线程在执行count++时,(假设此时count=1),线程1执行步骤2,还没有执行步骤3,那么内存中的count还是1;
    此时线程执行步骤1,那么读取的count值还是1,不是2,那么就会出现两个线程打印一样的数字了

    点赞 2 评论 复制链接分享
  • xiangzheniunai xiangzheniunai 4年前

    计算机内存中最快的是寄存器,直接和cpu交互,count++底层是改变寄存器中0->1,1->0实现变量的自增,速度不是一般的快,第一个线程system.out
    之后,count就瞬间自增完了,下一个线程输出时就是自增自后的count

    点赞 1 评论 复制链接分享
  • zzhao114 Z. ZHANG 4年前

    让我想起了我当初刚学java时候,期末考试题,火车订票系统。。。。

    点赞 评论 复制链接分享
  • baidu_26611019 蚂蚁冲锋队 4年前

    纠正:通过测试发现
    public class StaticTest {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    CountThread mThread = new CountThread();
    for (int i = 0; i < 100; i++) {
    Thread thread = new Thread(mThread);
    thread.start();
    }
    }
    }

    class CountThread implements Runnable {
    private static int count = 0;

    public void run() {
    try {
    Thread.sleep(1000);
    System.out.println("count : " + count++);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    };

    结果中有:
    count : 47
    count : 47

    出现了重复,原因在查找中...

    点赞 评论 复制链接分享
  • baidu_26611019 蚂蚁冲锋队 4年前

    楼主的意思是:线程的运行是异步的,会不会出现一个线程在前一个线程还没有对count完成++之前对它进行++命令,导致两个线程的结果一样?
    这种情况是不会发生的:楼上的所说的速度问题,其实就算速度不快也不会发生,static 变量 count 申请的内存地址在所有线程执行时都不会改变,
    意味着对同一个内存地址的内容做修改绝对不会同时发生,只要有先后就会一直累加上去

    点赞 评论 复制链接分享
  • zhangpan_soft zhangpan_soft 4年前

    你的count++会跳越,比如说你设置上限是20,假如有10个线程,可能同时访问到20,那么进行++操作,就有可能变为30,假如有100万并发量,那么损失将是无法计算的,曾经淘宝就在并发量上吃了一次亏,所以对于多线程操作,就要用多线程的变量,不要用普通变量,就比说int,那么java中对应有AotmicInteger的类,是线程安全的,就不存在两个线程拿到统一个数据的情况,jdk有个current的包,那个包下面全是线程并发相关的,多看看,dueg lea先生写的,最好买本将线程并发的书,不要买中文的,买英文的.ok!欢迎关注!

    点赞 评论 复制链接分享
  • xiangzheniunai xiangzheniunai 4年前

    count++是速度很快,只是变换寄存器里的位,比System.out.println等函数快不是一个级别

    点赞 评论 复制链接分享
  • strongerzhi Kolamu 4年前

    这个你可以从内存的角度来考虑,你在内存里面申请了一段公共空间,你每次只是执行读取内存,然后再写入内存,虽然是多线程,但是对于同一个地址的内存是不会同时给两个线程同时读取,加上你读取和写入的时间非常短,所以这个概率基本是不存在的!

    点赞 评论 复制链接分享
  • strongerzhi Kolamu 4年前

    如果你在读取和写入中间加一个等待,那么,这个是肯定会有重复的,也就是说
    system.out.println(count);
    wait(1000);
    count++;

    这个重复就会很明显

    点赞 评论 复制链接分享

相关推荐