[英]Static variable usage while using Fork-Join
问题陈述:-//这是一个示例,实际数组大小非常大
假设有A班
public class A{
public static int aa[]=new int[5];
public computeaa(){
for(int i=0;i<5;i++)
aa[i] = useaa(i);
}
//this below function can compute aa[i] value
public int useaa(int i){
if(i<=0)
return 1;
if(aa[i]!=0)
return aa[i];
else
return useaa[i-1]+useaa[i-2];
}
}
和RecursiveAction类B
@Override
protected void compute() {
// TODO Auto-generated method stub
A z=new A();
A.computeaa();
}
public static void main(String[] args) {
List<B> tasks =new ArrayList<B>();
for(int i=1; i<=2; i++){
//There is 2 fork will created
B =new B();
tasks.add(B);
B.fork();
}
if (tasks.size() > 0) {
for (B task : tasks) {
task.join();
}
}
}
怀疑?
假设分叉1计算静态变量aa [2],并且假设当分叉2将要计算aa [2]时,此分叉2能否获得由fork1计算的值aa [2]或将单独计算?
据我了解,在某些情况下fork 2可以轻松访问fork1的aa,假设fork 2要计算aa [3],它可以获取已经由fork 1计算的值。但是问题在于,假设fork 1将尝试计算aa [4],要计算aa [4],需要aa [3],叉子1已经计算过了,但是如果叉子1尝试获取aa [3],它是否有可能,但是偶然地它获得了aa [3]的访问权没有计算的叉子1的...再次造成混乱。
我很困惑,请加入fork
有一个简单的问题,我想计算一个由同一类使用的数组,但是在创建多个对象的同时,我想使用由另一个对象计算的同一数组,从而减少了计算时间。
我如何才能将该数组复制或获取到另一个对象,以便该对象不需要计算?
- 假设分叉1计算静态变量aa [2],并且假设当分叉2将要计算aa [2]时,此分叉2能否获得由fork1计算的值aa [2]还是将其单独计算?
假设这两个B
任务在不同的线程中运行-您选择不对它们执行任何控制-这两个线程正在访问同一数组对象的同一元素而没有任何同步。 每个线程都可以读取另一个线程写入的值。 此外,如果他们再次访问该数组元素,则它们可能会读取不同的值。 程序未正确同步,因此不能保证顺序一致性。
- 据我了解,在某些情况下fork 2可以轻松访问fork1的aa,假设fork 2要计算aa [3],它可以获取已经由fork 1计算的值。但是问题在于,假设fork 1将尝试计算aa [4],要计算aa [4],需要aa [3],叉子1已经计算过了,但是如果叉子1尝试获取aa [3],它是否有可能,但是偶然地它获得了aa [3]的访问权没有计算的叉子1的...再次造成混乱。
是的,您做出正确的判断-无论是关于可能的行为还是一团糟。
有一个简单的问题,我想计算一个由同一类使用的数组,但是在创建多个对象的同时,我想使用由另一个对象计算的同一数组,从而减少了计算时间。 我如何才能将该数组复制或获取到另一个对象,以便该对象不需要计算?
在某些情况下,您可能有不同的线程并行计算数组的不相交部分。 但是,由于数据之间的依赖性,问题中提出的计算不适合该计算。 由于在计算前一个索引2之前无法计算出索引1之后的元素,因此需要以一种或另一种方式序列化元素的计算。 您只能通过将单个线程投入到工作中来实现这一目标。
这样的计算完成后,您可以在线程之间共享初始化的数组,只要它们以一种或另一种方式与计算完成同步。 如果在初始计算完成后有任何线程修改了数组,则需要附加的同步要求。
您的特殊情况有些棘手,因为几乎没有具有同步意义的动作。 特别是,您的数组元素不是(也不能是final
,并且您不能确信仅在fork()
时才启动运行任务的线程。 如果您拥有后者,那么主线程之前所做的一切都会自动与任务工作同步。 实际上,您可以执行以下操作:
public class A {
// not static:
public int aa[] = new int[5];
public void computeAa() {
aa[0] = 1;
aa[1] = 1;
for (int i = 2; i < aa.length; i++) {
aa[i] = aa[i - 1] + aa[i - 2];
}
}
public int getAa(int i) {
return (i < 0) ? 1 : aa[i];
}
}
public class B extends RecursiveAction {
private A myA;
public RecursiveAction(A a) {
myA = a;
}
@Override
protected void compute() {
synchronized (myA) {
// ensure that myA's initialization is complete
while (myA.aa[0] == 0) {
// not yet initialized
myA.wait();
}
}
// ... do something with myA (without modifying it) ...
}
public static void main(String[] args) {
A theA = new A();
synchronized(theA) {
// synchronize the initialization of theA, because other threads will
// check it
theA.computeAa();
// wake up any threads waiting on the initialization
theA.notifyAll();
}
List<B> tasks = new ArrayList<B>();
for(int i = 1; i <= 2; i++){
//There is 2 fork will created
B = new B(theA);
tasks.add(B);
B.fork();
}
for (B task : tasks) {
task.join();
}
}
}
请注意,主线程创建A
的实例并在分派任何任务之前对其进行初始化。 它为每个B
提供实例(因此他们共享它)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.