sample
长度相同的新字符串tmp
。
class T10 {
static String tmp = "", sample = "Manipulate";
public static void main(String args[]) {
for(int i=0;i<sample.length();i++)
new Thread10(i).t.start();
System.out.println(tmp);
}
}
class Thread10 implements Runnable {
int i;
Thread t;
Thread10(int i) {
t = new Thread(this, "Manipulator Thread : "+i);
this.i = i;
}
public void run() {
T10.tmp+=T10.sample.charAt(i);
}
}
以下是一些示例输出:
Mnla
Maniplua
Mpia
Miap
Mu
首先,您需要了解两件事:
- 您不能在Java中更改字符串。代码看起来像修改字符串总是创建一个新字符串并丢弃前一个
+=
不是单一操作,而是三个操作(读取、修改、回写(
您可以想象,在您的代码中,当两个线程同时读取字符串时,它们读取的值相同(例如"Man"(。然后第一个线程创建一个新的字符串(添加它自己的字母,例如"Mani"(,第二个线程创建另一个新字符串(例如"Manp"(。现在,他们都将对其新值的引用放入字段tmp
;取决于哪一个";获胜";,其中一个字符将永远不会被其他线程看到。注意,在";真实的";程序中,问题更复杂(优化开始(,您确实需要了解Java内存模型才能编写正确的代码。
要解决您的问题,您需要:
-
停止使用字符串(不能修改,需要使用新字符串它们的位置(,而是使用存储字符的可变对象;一所有线程都可以看到并写入的单个对象;
-
确保该对象";行为正确";与一起使用时多个线程(在Java中,这意味着对象是并发或同步(
实际上,Java有一个非常古老的类(现在很少使用(,非常适合您的情况:StringBuffer。
使用StringBuffer
而不是String
作为tmp
;则使用CCD_ 8而不是CCD_。
请告诉我们您希望从代码中得到什么输出。
一般来说:
在您的实现中,您确实启动了10个线程(因为sample
字符串有10个字母(。但是,您绝对无法控制线程的执行顺序和此时tmp
变量的状态。
这可能会导致字母和字母的混合顺序相互覆盖(如输出中所示(。
一旦您指定了期望的输出,就可以提出解决方案。