小编Raf*_*ffy的帖子

带有System.exit的Java静态块关闭挂钩

这段代码会死锁:

public class Main {
   static public final Object a = new Object();
   static {
      Runtime.getRuntime().addShutdownHook(new Thread() {
         @Override
         public void run() { if (a == null); }
      });
      System.exit(0);
   }
   static public void main(final String[] args) {}
}
Run Code Online (Sandbox Code Playgroud)

此代码将正常退出:

public class Main {
   static public final Object a = new Object();
   static {
      final Object aa = a;
      Runtime.getRuntime().addShutdownHook(new Thread() {
         @Override
         public void run() { if (aa == null); }
      });
      System.exit(0);
   }
   static public void main(final String[] …
Run Code Online (Sandbox Code Playgroud)

java static deadlock

14
推荐指数
2
解决办法
5592
查看次数

线程池,共享数据,Java同步

说,我有一个数据对象:

class ValueRef { double value; }

每个数据对象存储在主集合中的位置:

Collection<ValueRef> masterList = ...;

我还有一组作业,其中每个作业都有一个本地的数据对象集合(每个数据对象也出现在其中masterList):

class Job implements Runnable { 
     Collection<ValueRef> neededValues = ...; 
     void run() {
         double sum = 0;
         for (ValueRef x: neededValues) sum += x;
         System.out.println(sum);
     } 
}
Run Code Online (Sandbox Code Playgroud)

用例:

  1. for (ValueRef x: masterList) { x.value = Math.random(); }

  2. 使用某些作业填充作业队列.

  3. 唤醒线程池

  4. 等到每个工作都被评估

注意:在作业评估期间,所有值都是常量.但是,线程可能已经评估过去的作业,并保留缓存的值.

问题: 确保每个线程看到最新值所需的最小同步量是多少?

我理解从monitor/lock-perspective进行同步,我不理解从cache/flush-perspective进行同步(即,在同步块的进入/退出时内存模型保证了什么).

对我来说,感觉我需要在更新值的线程中同步一次以将新值提交到主内存,并且每个工作线程一次,以刷新缓存以便读取新值.但我不确定如何最好地做到这一点.

我的方法:创建一个全局监视器:static Object guard = new Object(); 然后,同步guard,同时更新主列表.最后,在启动线程池之前,对池中的每个线程执行一次,guard在空块中进行同步.

这真的会导致该线程读取的任何值的完全刷新吗?或者只是在同步块内触及的值?在这种情况下,可能我应该在循环中读取每个值一次,而不是空块?

谢谢你的时间.


编辑:我认为我的问题可归结为,一旦我退出同步块,每次第一次读取(在该点之后)都会进入主存储器吗?无论我同步什么?

java synchronize threadpool

6
推荐指数
1
解决办法
1577
查看次数

标签 统计

java ×2

deadlock ×1

static ×1

synchronize ×1

threadpool ×1