这是一个示例代码,我写这篇文章只是为了让您理解我在下面写的问题。 这是一个类,它有一个为不同的a计算某个值的示例方法;
public class Class1{
public int examplemethod(int a){
int k = a*2;
int b=k+1;
......some more manipulation
return k;
}
}
下面的课程将平行调用上述方法
public class Class2 extends RecursiveTask<Integer>{
int a=0;
Class1 obj;
public Class2(int a, Class1 obj){
this.a = a;
this.obj=obj;
}
@Override
protected Integer compute () {
return obj.examplemethod(a);
}
public static void main(Strings[] args){
List<Class2> list =new ArrayList<Class2>();
Class1 obj = new Class1();
for(int i=4;i<7;i++){
Class2 obj2=new Class2(obj);
obj2.fork();
list.add(obj2);
}
int arr[]=new int[4];
int i=0;
if(list.size>0){
for(Class2 ob:list){
arr[i++]= ob.join();
}
}
}
}
我在for循环中创建了class2的三个对象,所以假设第一个fork将使用a = 4计算值,但是当它在examplemethod中计算时,cpu shedule另一个线程让fork 2表示a = 5并保存程序fork 1线程的计数器,现在使用a = 5计算值时,它更改了fork1之前更改的examplemethod中的一些变量,所以现在我的问题是,如果examplemethod是在该类的所有对象之间共享的资源,如果一个对象在函数中进行一些更改(在线程切换)其他一些对象来了并改变了相同的变量然后我的输出会受到影响但问题是我得到了正确的答案,所以我的概念落后于并行线程,Threads将共享一个公共资源,因此我的代码中的关键部分在哪里。
答案 0 :(得分:1)
代码中的线程之间共享哪个资源?
简而言之,class1
是线程安全的,因为方法中定义的变量不能被另一个线程更改。
虽然class2
不是 - 当且仅当两个线程可以同时使用class2
的同一个实例(也称为Singleton)并且线程更改某个实例变量时,而另一个使用它。 / p>
class2
- int a
中只有一个实例变量。
但在代码中我没有看到任何类型的Singleton或实例变量"a"
更改......
每个线程都有一个新的class2实例:Class2 obj2=new Class2();
(实际上它必须是Class2 obj2=new Class2(aValue);
)
我错过了什么吗?
答案 1 :(得分:1)
在方法内声明的变量是局部变量,具有特定方法调用的特定值。您应该首先独立于多线程方面理解该概念。例如。将打印以下程序:
public class Test {
public static void main(String[] args) {
test(5);
}
private static void test(int i) {
System.out.println("enter test with "+i);
if(i>0) test(i-1);
System.out.println("leave test with "+i);
}
}
当多个线程执行相同的方法时,这些变量的本地特性不会改变。这些处决之间没有干涉。
同样,实例变量,即在没有static
修饰符的类中声明的成员变量。保存特定于特定对象实例的值,因此,如果创建多个实例,它们可以为这些变量设置不同的值,而不会相互影响。
这些构建块用于构建多线程程序,而无需始终进行线程同步。如果创建表示要执行的不同任务的不同对象,并且这些任务仅执行使用这些对象的方法和/或方法参数(方法参数是局部变量)来计算结果,则任务已经被隔离。
您必须所做的事情,正在修改共享对象的static
变量或实例变量。在您的代码中,没有共享对象。