qq_39494095 2019-05-03 17:31 采纳率: 0%
浏览 272

为什么每个线程输出的counter大小不一,先输出的可能比后输出的要大?

在用多线程去测试race condition的时候,出现了前后输出但总次数大小不一的情况,最关键大小不是增序而是无序。求大神解答!谢谢!

package ThreadTry;

import java.util.Scanner;

/**
 * Created by Administrator on 2019/5/2 0002.
 */
public class Homework {
    public static void main(String args[]) throws InterruptedException {
        Th th1,th2,th3,th4,th5;
        System.out.println("请设定每个线程的睡眠时间(ms):");
        Scanner reader=new Scanner(System.in);
        int t=reader.nextInt();
        Th.setTime(t);
        Th th=new Th();
        Thread thread1,thread2,thread3,thread4,thread5,thread6,thread7,thread8,thread9,thread10;
        thread1=new Thread(th);
        thread1.setName("线程1");
        thread2=new Thread(th);
        thread2.setName("线程2");
        thread3=new Thread(th);
        thread3.setName("线程3");
        thread4=new Thread(th);
        thread4.setName("线程4");
        thread5=new Thread(th);
        thread5.setName("线程5");
        thread6=new Thread(th);
        thread6.setName("线程6");
        thread7=new Thread(th);
        thread7.setName("线程7");
        thread8=new Thread(th);
        thread8.setName("线程8");
        thread9=new Thread(th);
        thread9.setName("线程9");
        thread10=new Thread(th);
        thread10.setName("线程10");
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();
        thread6.start();
        thread7.start();
        thread8.start();
        thread9.start();
        thread10.start();
        thread1.join();
        thread2.join();
        thread3.join();
        thread4.join();
        thread5.join();
        thread6.join();
        thread7.join();
        thread8.join();
        thread9.join();
        thread10.join();
        System.out.println("次数="+th.getCounters());
    }
}
class Th implements Runnable {
    int counter = 0;
    static int t = 0;

    static void setTime(int x) {
        t = x;
    }

    @Override
    public void run() {
        String name=Thread.currentThread().getName();
        for (int i = 0; i < 1000; i++) {
            counter++;
            try {
                Thread.sleep(t);
            }
            catch (InterruptedException e) {
            }
        }
        System.out.println("我是"+name+"次数="+counter);
    }
    int getCounters(){
        return counter;
    }
}

这个是输出结果:
图片说明

  • 写回答

2条回答 默认 最新

  • hujiasuta 2019-05-03 18:09
    关注

    counter是成员变量,这意味着它是在线程之间共享的,所以需要同步。

    counter++不是原子操作。
    它实际上存在3个步骤
    a 把counter当前的值读取到cpu的寄存器
    b cpu对它+1
    c 然后将结果写回counter
    如果第一个线程完成了a步骤,然后被挂起,此时执行第二个线程,并且完成了abc三个步骤,此时counter被+1,然后线程1继续执行,此时cpu里面的值还是没有+1之前的值。
    它+1后也写回,按理说,应该再+1,但是实际上因为它是在没有+1的情况下+1,所以只加了一个1。运行很多次,当这个情况出现了很多次,最后的结果就少了一些。

    评论

报告相同问题?

悬赏问题

  • ¥15 fluent的在模拟压强时使用希望得到一些建议
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流
  • ¥15 Rstudio 保存代码闪退