Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在一个有多个线程的程序中,我可能会遇到什么问题?_Java_Multithreading_Thread Safety - Fatal编程技术网

Java 在一个有多个线程的程序中,我可能会遇到什么问题?

Java 在一个有多个线程的程序中,我可能会遇到什么问题?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,假设我有两个线程都可以访问同一个游戏世界实例。游戏世界有一个列表,线程可以通过方法doAction(Action-Action,Map-value)更改并影响实体。每个实体都有一个值映射。根据doAction方法中的操作和值,实体将以不同的方式更改 假设doAction方法是唯一可以更改实体列表的方法,那么我是否会遇到任何问题?如果两个线程同时更改同一实体,会发生什么情况?可以在一个实例上同时运行多个方法吗?如果是这样,同一方法是否可以同时运行两次 这会导致很多很多问题。 下面是一个列表:(这不

假设我有两个线程都可以访问同一个游戏世界实例。游戏世界有一个列表,线程可以通过方法doAction(Action-Action,Map-value)更改并影响实体。每个实体都有一个值映射。根据doAction方法中的操作和值,实体将以不同的方式更改


假设doAction方法是唯一可以更改实体列表的方法,那么我是否会遇到任何问题?如果两个线程同时更改同一实体,会发生什么情况?可以在一个实例上同时运行多个方法吗?如果是这样,同一方法是否可以同时运行两次

这会导致很多很多问题。 下面是一个列表:(这不是每一个,因为有这么多)

  • 并发性-当您“并发”访问多个线程上的字段时。 进一步阅读: 同步/
  • 死锁-当两个线程是块等待对方时。 进一步阅读:
  • 同步-当两个线程正在修改一个字段或调用一个方法时,它们无法跟上彼此,并且一些修改不会被记录。 例子: 如果我运行以下代码,我们希望最终打印的总数为2000000,因为每个线程应该增加1000000
static int-total=0;
公共静态void main(字符串[]args){
新线程(()->{
对于(int i=0;i<100000;i++){
总计++;
System.out.println(“添加了线程1!新总数:“+total”);
}
}).start();
新线程(()->{
对于(int i=0;i<100000;i++){
总计++;
System.out.println(“添加了线程2!新总数:“+total”);
}
}).start();
}
但是,控制台的最后几行如下所示:

Thread 2 added! New total: 199996
Thread 2 added! New total: 199997
Thread 2 added! New total: 199998
我们可以看到,这是一个不可接受的结果。 不过,这只需使用
synchronized
关键字即可解决。 如果我们运行这个,我们会得到想要的2000000的结果

static int-total=0;
静态同步的void add(){
总计++;
}
公共静态void main(字符串[]args){
新线程(()->{
对于(int i=0;i<100000;i++){
添加();
System.out.println(“添加了线程1!新总数:“+total”);
}
}).start();
新线程(()->{
对于(int i=0;i<100000;i++){
添加();
System.out.println(“添加了线程2!新总数:“+total”);
}
}).start();
}

,举几个例子。第二件事可能会以你意想不到的顺序发生。首先用线程编程需要考虑共享字段的同步。RE:……同时由两个线程改变。“假设您有一个<代码> int i=0;<代码>,线程A设置
i=1螺纹B组<代码>i=2,线程C调用
System.out.println(i)
如果线程之间没有同步,那么您就有一个争用条件:无法预测线程C是否将打印
0
1
2
。另外,假设您的“实体”由几个不同的字段描述,假设字段之间存在一些必须保留的重要关系。即使只有一个线程更新实体,它也必须逐个更新字段。如果线程之间没有同步,其他线程可能会查看实体,并看到它处于半更改状态——可能是无效或非感官的半更改状态。