Java 创建1000个线程来修改一个值,但是虽然我使用了join,但值总是不一样的
答案应始终为500,但它不断变化 我运行了1000个线程,如果该线程是奇数,它应该使用循环将总和递减100000次,如果偶数递增100001次 虽然我使用了join方法,但答案一直在变化,有什么建议吗Java 创建1000个线程来修改一个值,但是虽然我使用了join,但值总是不一样的,java,multithreading,Java,Multithreading,答案应始终为500,但它不断变化 我运行了1000个线程,如果该线程是奇数,它应该使用循环将总和递减100000次,如果偶数递增100001次 虽然我使用了join方法,但答案一直在变化,有什么建议吗 package softwaredesign.assignment1; public class SoftwareDesignAssignment1 { public static class T implements Runnable{ int e=0; T(int z){
package softwaredesign.assignment1;
public class SoftwareDesignAssignment1 {
public static class T implements Runnable{
int e=0;
T(int z){
e=z;
}
public void run(){
if(e==1){
for(int i=0;i< 100001;i++)
SoftwareDesignAssignment1.sum+=e;
}
else{
for(int i=0;i< 100000;i++)
SoftwareDesignAssignment1.sum=sum+e;
}
}
}
public static int sum=0;
public static void main(String[] args) throws InterruptedException {
Thread[] t=new Thread[1000];
for(int i=0;i<1000;i++){
if(i%2==0)
t[i]=new Thread(new T(1));
else
t[i]=new Thread(new T(-1));
}
for(Thread tt:t){
tt.start();
}
for(Thread tt:t){
tt.join();
}
System.out.print(sum);
}
软件包设计.assignment1;
公共类软件设计1{
公共静态类T实现可运行{
int e=0;
T(整数z){
e=z;
}
公开募捐{
如果(e==1){
对于(int i=0;i<100001;i++)
软件设计1.sum+=e;
}
否则{
对于(int i=0;i<100000;i++)
软件设计1.sum=sum+e;
}
}
}
公共静态整数和=0;
公共静态void main(字符串[]args)引发InterruptedException{
线程[]t=新线程[1000];
对于(int i=0;i,线程要更新该值,必须执行以下操作:
将值从内存读入寄存器
向寄存器中的值添加1
将更新后的值存储回内存
现在,假设有两个线程试图同时执行此操作。首先将内存中的值设置为0。下面是可能发生的情况:
线程1将值0读入寄存器
线程1更新寄存器中的值
线程2将值0读入寄存器
线程1将值1存储到内存中
线程2更新寄存器中的值
线程2将值1存储到内存中
两个线程都已执行,但由于它们都在处理同一个值副本,因此似乎只有一个线程更新了该值
另一种可能发生的情况是,编译器可以假设它以独占方式访问内存中的值。当它看到以下代码时:
for (int i = 0; i < 1000; ++i)
{
SoftwareDesignAssignment1.sum+=e;
}
for(int i=0;i<1000;++i)
{
软件设计1.sum+=e;
}
编译器通过将值加载到内存中一次,递增1000倍,然后将值存储回内存来优化代码。它没有理由执行“加载、递增、存储”操作1000次。如果程序中有多个线程发生这种情况,结果将是1000或-1000,这取决于最后完成的是递增线程还是递减线程
解决此问题的方法有很多,包括使用原语,如锁、联锁指令和特定于语言的同步操作。注释中的链接将帮助您了解Java语言的细节。+=
首先是。搜索“线程安全”和“线程原子”。这也应该包含在源材料中,通常在处理synchronized
@user2864740 Ok,谢谢:)代码的结果应该是不可预测的,因为(如前所述)它不是线程安全的。