为什么不在此代码中进行同步?

时间:2015-05-28 06:46:30

标签: java multithreading synchronization

package atask;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class Q3Synchronization 
{
    Integer sum=new Integer(0);

     Q3Synchronization(){
         ExecutorService e=Executors.newFixedThreadPool(1000);
         for(int i=0;i<1000;i++){
             e.execute(new Sum());
         }
         e.shutdown();

         while(!e.isTerminated()){

         }
         System.out.println(sum);
     }
    public static void main(String[]args){
        new Q3Synchronization();
    }

     class Sum implements Runnable{


        @Override
        public void run() {

            m();

        }
       public synchronized void m(){
             sum=sum+1;
         }
     }

}

问题是:

  • (同步线程)编写一个启动1,000个线程的程序。每个线程将1添加到最初为0的变量sum。您需要通过引用传递sum到每个线程。为了通过引用传递它,定义一个Integer包装器对象来保存sum。使用和不使用同步运行程序以查看其效果。

2 个答案:

答案 0 :(得分:1)

简而言之

对象方法同步/锁定基于每个实例工作。

说明

您正在创建Sum类的1000个实例。对m()的每次调用都是同步的,但不会导致任何其他线程等待。这是因为没有对同一实例的并发调用,而是对不同实例的调用。我附上了一些小改动代码:

     Sum s = new Sum();
     for(int i=0;i<1000;i++){
         e.execute(s);
     }

如果您尝试此更改,您的计数器变量中将始终得到1000的结果。

答案 1 :(得分:0)

在构造函数中,您正在创建cd /opt/squid-3.5.4_BKUP/libltdl/ touch configure.ac aclocal.m4 configure Makefile.am Makefile.in 实例并将其传递给单独的线程。方法new Sum()在对象上获取锁(当进入同步块时每个线程必须获取锁)。因此,每个线程可以同时执行m()方法,这会破坏您的多线程逻辑,因为m()不是原子操作。

您可以修复它:

  1. 将sum变量更改为Atomic Integer并使用(sum = sum + 1)执行添加。 E.g。
  2. addAndGet()

    和方法AtomicInteger sum= new AtomicInteger(0);使用原子整数

    m

    2.使用相同的对象获取锁定,以便方法public void m(){sum.addAndGet(1);}能够正确同步。您可以通过在构造函数中创建一个m实例变量来实现它。

    sum