假设我有两个线程都可以访问同一个gameWorld实例。 gameWorld有一个List,线程可以使用doAction(Action action,Map values)方法更改影响实体。每个实体都有一个值映射。根据doAction方法中的操作和值,将以不同方式更改实体。
假设doAction方法是可以更改实体列表的唯一方法,我可能会遇到任何问题吗?如果两个线程同时更改同一实体,将会发生什么情况?可以在一个实例上同时运行多个方法吗?如果是这样,同一方法可以同时运行两次吗?
答案 0 :(得分:3)
这可能导致很多很多问题。 以下是其中的一些列表:(由于数量太多,所以不是每一个)
static int total = 0;
public static void main(String[] args) {
new Thread(() -> {
for (int i = 0; i < 100000; i++) {
total++;
System.out.println("Thread 1 added! New total: " + total);
}
}).start();
new Thread(() -> {
for (int i = 0; i < 100000; i++) {
total++;
System.out.println("Thread 2 added! New total: " + total);
}
}).start();
}
但是,控制台的最后几行如下:
Thread 2 added! New total: 199996
Thread 2 added! New total: 199997
Thread 2 added! New total: 199998
我们看到,这是不可接受的结果。
但是,这可以通过synchronised
关键字简单地解决。
如果运行此命令,我们将得到2000000的结果。
static int total = 0;
static synchronized void add() {
total++;
}
public static void main(String[] args) {
new Thread(() -> {
for (int i = 0; i < 100000; i++) {
add();
System.out.println("Thread 1 added! New total: " + total);
}
}).start();
new Thread(() -> {
for (int i = 0; i < 100000; i++) {
add();
System.out.println("Thread 2 added! New total: " + total);
}
}).start();
}