sinat_25596967
梁不正
采纳率18.2%
2015-07-09 04: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后的结果大概是九百多
为什么会有这样的差异?

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

9条回答

  • tongyi55555 JonsonJiao 6年前

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

    点赞 1 评论 复制链接分享
  • danielinbiti danielinbiti 6年前

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

      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
    }
    
    点赞 1 评论 复制链接分享
  • bhdgx Soulic 6年前

    可以利用Thread.join()方法让主线程等待所有的子线程运行结束,如

         for (int i = 0; i < 1000; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Vs.inc();
                }
            });
            thread.start();
            thread.join();
        }
    
    点赞 评论 复制链接分享
  • bhdgx Soulic 6年前

    在你这个列子中,要想在main方法中打印的count值为1000,就需要等待所有的子线程运行结束才行,利用Thread.join()方法就可以了。
    将创建线程的代码改成

         for (int i = 0; i < 1000; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Vs.inc();
                }
            });
            thread.start();
            thread.join();
        }
    
    点赞 评论 复制链接分享
  • bhdgx Soulic 6年前

    要想在主线程中得到count的值是1000,主线程必须要等待所有的子线程运行完才行,利用Thread.join()方法就可以了。将你创建线程的地方改成以下代码:

         for (int i = 0; i < 1000; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Vs.inc();
                }
            });
            thread.start();
            thread.join();
        }
    
    点赞 评论 复制链接分享
  • GQB_CMD GQB_CMD 6年前

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

    点赞 评论 复制链接分享
  • frank_20080215 frank_20080215 6年前

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

    点赞 评论 复制链接分享
  • Unkown_Answer Unkown_Answer 6年前

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

    点赞 评论 复制链接分享
  • lingfeiwen Brankily 6年前
     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);
        }
    
    点赞 评论 复制链接分享

相关推荐