2017-10-08 80 views
-1

我认为Java中的同步方法是一次执行一次。 但是,我看到如果2个可调用函数正在通过同步块,它们将并行执行。Java可调参数不同步

这是我的固定线程池的Executor类。

public class ThreadExecutor 
{ 

    ExecutorService executors = Executors.newFixedThreadPool(100); 
    public void callCallable2() 
    { 
     System.out.println("Inside executor callable 2 method"); 
     ThreadTestCallable2 t = new ThreadTestCallable2(); 
     executors.submit(t); 
     System.out.println("Exiting executor callable 2 method"); 
    } 

    public void callCallable1() 
    { 
     System.out.println("Inside the executor callable 1 method"); 
     ThreadTestCallable1 t = new ThreadTestCallable1(); 
     executors.submit(t); 
     System.out.println("exiting the executor callable 1 method"); 
    } 

} 

我可调用的类是:

public class ThreadTestCallable1 implements Callable { 

    @Override 
    public Object call() throws Exception { 
     System.out.println("Inside the threadtestcallable 1"); 
     ThreadHelperTest t = new ThreadHelperTest(); 
     t.test(); 
     System.out.println("Exiting the threadtestcallable 1"); 
     return null; 
    } 

} 

public class ThreadTestCallable2 implements Callable{ 

    @Override 
    public Object call() throws Exception { 
     System.out.println("Inside the threadtestcallable 2"); 
     ThreadHelperTest t = new ThreadHelperTest(); 
     t.test(); 
     System.out.println("exitting the threadtestcallable 2"); 
     return null; 
    } 


} 

我调用同步方法是在辅助类。

public class ThreadHelperTest 
{ 
    public void test() 
    { 
     test1(); 
    } 

    public synchronized void test1() 
    { 
     try { 
      System.out.println("Sleeping for 10 sec's T-name: "+ 
      Thread.currentThread().getName()); 
      Thread.sleep(60000); 
      System.out.println("wokeup T-Name: "+ 
      Thread.currentThread().getName()); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

这里是我的主类:

public class ThreadTest { 

    public static void main(String arg[]){ 

     ThreadExecutor t = new ThreadExecutor(); 
     t.callCallable1(); 
     t.callCallable2(); 
    } 

} 

为上述执行最终输出是我看到的可调用对象进入的时间同步方法,这是不应该的,什么毛病监视对象。?

请找到上述代码的结果:

Inside the executor callable 1 method 
exiting the executor callable 1 method 
Inside executor callable 2 method 
Inside the threadtestcallable 1 
Exiting executor callable 2 method 
Inside the threadtestcallable 2 
Sleeping for 10 sec's T-name: pool-1-thread-1 
Sleeping for 10 sec's T-name: pool-1-thread-2 
wokeup T-Name: pool-1-thread-1 
Exiting the threadtestcallable 1 
wokeup T-Name: pool-1-thread-2 
exitting the threadtestcallable 2 

如果有什么需要改变,请给我建议。 以获得这些方法的同步。

+0

我怀疑这里的问题是创建新的对象,从而为两个对象创建两个不同的监视器。 如果这种情况下,请提出任何替代计划,以实现可卡拉之间的同步。 –

+0

'ThreadTestCallable1'和'ThreadTestCallable2'必须有一个字段'ThreadHelperTest t'。然后,您创建可调用对象并传入'ThreadHelperTest'的同一个实例。 – luk2302

+0

这里的问题是肯定**,你有多个ThreadHelperTest实例。规则是一个非静态的'synchronized'在同一个实例*上提供对其他'同步'调用*的排除。你有不同的实例。因此在关系之前不会互相排斥,也不会发生同步。 –

回答

0

您的每个可调用对象都有自己的ThreadHelperTest实例。允许对不同实例的synchronized method进行交织。

首先,它是不可能的同步方法两次调用上同一对象交织。

您可以将ThreadHelperTest的相同实例传递给您的可调用对象,或使用任何其他共享互斥对象进行同步。

+0

任何使用Util.Concurrent.Locks的机会..? 需要做些什么才能实现这两个可调参数之间的同步。 有什么想法。? 我实际上也尝试过锁定机制,但这些也不工作,使用静态字段进行同步的任何想法。 –

+0

@AnilkumarPVV一切都在答案中。你并不需要'java.util.concurrent.locks',只是在共享的东西上进行同步。 – lexicore