我正在尝试并行化一些代码,这些代码在“常量”类中使用静态字段。目前的代码基本上就像这样
public class myClass{
public class Constants{
public static int constant;
}
public static void main(String[] args){
for(int i = 0 ; i<10 ; i++){
Constants.constant = i;
System.out.println(Constants.constant/2);
}
}
}
显然,循环中的代码更多地依赖于Constant类,而Constant本身要复杂得多。我想要做的是为循环的每次迭代创建一个线程,并分别进行所述计算,同时控制线程数(现在我正在使用一个简单的信号量)。 现在显然在上面的代码中,Constants类在线程之间共享,因此每个线程都不能更新它们而不为所有线程更新。
所以我的问题是:无论如何要使我的Constants类能够为每个线程创建一个实例,同时能够以静态方式访问其字段吗?
答案 0 :(得分:0)
您所描述的是thead-local:http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html。这是一件好事。但是,正如Affe指出的那样,你不能将它与你的代码一起使用,因为只有一个类的实例及其静态成员(每个类加载器)。如果您的Constants类可以并行构建多个副本,然后将它们合并在一起,则应通过删除“static”使Constants.constant成为实例变量。然后在myClass中创建一个thread-local,如下所示:
private ThreadLocal<Constants> constants = new ThreadLocal<Constants> {
@Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
}
一旦你的线程更新了他们的本地对象,他们就可以将它们粘贴到一个共享的ArrayBlockingQueue中。你的主线程可以将它们全部出列并根据需要合并它们。
另外需要注意的是,如果你有一个可变数量的迭代,可能很多,你可能想要使用一个线程池执行器而不是每次循环一个线程,但是你不需要那么多线程。 (线程创建成本很高,许多并发线程占用内存和操作系统调度资源。)