2 sinat 25596967 sinat_25596967 于 2015.07.09 12:14 提问

java 线程问题,谢谢大家了。

public class Vs {
public static int count = 0;

public synchronized static void inc() {

    //这里延迟1毫秒,使得结果明显

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        count++;
}

public static void main(String[] args) {

    //同时启动1000个线程,去进行i++计算,看看实际结果

    for (int i = 0; i < 1000; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Vs.inc();
            }
        }).start();
    }


    System.out.println("运行结果:Counter.count=" + Vs.count);
}

}

问题:为什么Synchronized没能将方法锁住。
加了Synchronized后得出的结果大概是一百多
去掉Synchronized后的结果大概是九百多
为什么会有这样的差异?

13个回答

danielinbiti
danielinbiti   Ds   Rxr 2015.07.09 12:19

不是没锁住,是因为线程是异步的

  System.out.println("运行结果:Counter.count=" + Vs.count);执行这句的时候线程还没执行完

你在

 public synchronized static void inc() {

    //这里延迟1毫秒,使得结果明显

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        count++;
                 System.out.println("运行结果2222:Counter.count=" + count);//这里加一句,最后一个肯定是1000
}
tongyi55555
tongyi55555   2015.07.09 12:58

可以再读一读java线程运行的有关知识,启动只是将其加入到执行队列中,并不是立即开始执行该线程,你输出的时候看到的结果并不是最终所有1000个线程都执行一次的结果,你的结果其实更说明了synchronized的作用,加了之后运行时必须等待其他已经执行的线程执行完才能执行,速度下降了,而没有加时,是不用等待的,执行速度更快等到的结果更大。

lingfeiwen
lingfeiwen   2015.07.09 13:20

1楼网友是正确的。主要是因为我们自己起的线程和主线程是并列执行的。

lingfeiwen
lingfeiwen   2015.07.09 13:23
 public static void main(String[] args) {
        //设置启动的总线程数
        int number = 1000;
        //创建倒数锁存器
        final CountDownLatch doneSignal = new CountDownLatch(number);


        //同时启动1000个线程,去进行i++计算,看看实际结果

        for (int i = 0; i < number; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Vs.inc();
                    //每个线程执行完自动减1
                    doneSignal.countDown();
                }
            }).start();
        }
        try {
            //在总数没减到0之前,使主线程(main线程一直等待)
            doneSignal.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("运行结果:Counter.count=" + Vs.count);
    }
lingfeiwen
lingfeiwen 一定要在main函数里面打印线程总数的话,看我上面的改动。
2 年多之前 回复
Unkown_Answer
Unkown_Answer   2015.07.09 13:46

恰恰相反,inc方法其实已经被锁住了,你之所以没有得到1000这个正确的数据是因为你的支线程还在等待线程锁的释放,主线程就已经结束了。你可以在主线程打印count之前先休眠一定时间,结果一定是1000。(从你得到100多这个数据可以看出你的cpu肯定不怎么好,,)

Unkown_Answer
Unkown_Answer   2015.07.09 13:46

恰恰相反,inc方法其实已经被锁住了,你之所以没有得到1000这个正确的数据是因为你的支线程还在等待线程锁的释放,主线程就已经结束了。你可以在主线程打印count之前先休眠一定时间,结果一定是1000。(从你得到100多这个数据可以看出你的cpu肯定不怎么好,,)

frank_20080215
frank_20080215   2015.07.09 14:46

加了Synchronized了后得出的结果大概是一百多,说明是

GQB_CMD
GQB_CMD   2015.07.09 15:35

你没保证所有线程已经执行完就把结果打印出来了,保证所有线程已经执行结束并且加了关键字之后肯定是1000

miracle_yao
miracle_yao   2015.07.09 16:30

同意1楼,主线程也是一个线程。

xiao6gui
xiao6gui   2015.07.09 20:27

恰恰相反,inc方法其实已经被锁住了,你之所以没有得到1000这个正确的数据是因为你的支线程还在等待线程锁的释放,主线程就已经结束了。你可以在主线程打印count之前先休眠一定时间,结果一定是1000。(从你得到100多这个数据可以看出你的cpu肯定不怎么好,,)

共13条数据 1 尾页
Csdn user default icon
上传中...
上传图片
插入图片