问题陈述: - //这是一个例子,实际数组大小非常大
假设有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();
}
}
}
疑问?
假设fork 1计算静态变量aa [2],并假设当fork 2计算aa [2]时,这个fork 2可以获得由fork1计算的值aa [2],或者它将计算seperately ??
根据我的理解,fork 2在某些情况下很容易访问fork1的aa,假设fork 2想要计算aa [3],它可以得到已经由fork 1计算的值。但是问题假设当fork 1尝试计算aa [4]时,为了计算aa [4],它需要aa [3],哪个fork 1已经计算过,但是如果fork 1试图得到aa [3]则可以,但是很有可能它获得了叉子1的aa [3]的访问权限,而不是计算...再次造成混乱。
我非常喜欢fork join kindly help
有一个简单的问题,我想计算一些由同一个类使用的数组,但是在创建多个对象时我想使用由其他对象计算的相同数组,这样我的计算时间就减少了。 /> 如何将该数组复制或获取到另一个对象,以便该对象不需要计算?
答案 0 :(得分:1)
- 假设fork 1计算静态变量aa [2],并假设当fork 2计算aa [2]时,这个fork 2可以得到值aa [2] 这是由fork1计算的,还是单独计算的?
醇>
假设两个B
任务在不同的线程中运行 - 您选择不执行任何控制 - 这两个线程正在访问同一个数组对象的相同元素而没有任何同步。任何一个线程都可以读取另一个线程写入的值。此外,如果再次访问该数组元素,它们可能会读取不同的值。程序未正确同步,因此无法保证顺序一致性。
- 根据我的理解,fork 2在某些情况下很容易访问fork1的aa,假设fork 2想要计算aa [3],它可以得到的值 已经由fork 1计算了。但问题是假设fork 1 将尝试计算aa [4],为计算aa [4],它需要aa [3],其中 fork 1已经计算过但是如果fork 1试图获得它可能 aa [3],但偶然它可以获得分叉1的aa [3] 不计算......再次造成混乱。
醇>
是的,你正确地判断 - 关于可能的行为以及它是一团糟。
有一个简单的问题,我想计算一些使用的数组 同一个类,但在创建多个对象时,我想使用 由其他对象计算的相同数组,以便我的计算 时间减少了。我如何将该数组复制或获取到另一个对象,所以 该对象不需要计算?
在某些情况下,您可能有不同的线程并行计算数组的不相交部分。然而,由于数据之间的依赖性,问题中提出的计算不适用于此。因为在计算前两个之前不能计算过去索引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
提供了该实例(因此他们共享它)。