我在片段下面运行,我得到了意想不到的行为。可能它正在以正确的方式工作,但我需要让它以其他方式工作。详情如下。
import java.util.ArrayList;
import java.util.List;
public class TaskExample {
public static void main(String[] args) throws InterruptedException {
final PositionHolder holder = new PositionHolder();
final List<Integer> data = new ArrayList<Integer>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 20; i++) {
holder.setPosition(i);
Thread t = new Thread() {
@Override
public void run() {
data.add(holder.getPosition());
}
};
t.start();
threads.add(t);
}
for (Thread thread : threads) {
thread.join();
}
for(int i : data){
System.out.println(i);
}
}
}
class PositionHolder {
int position = 0;
public void setPosition(int position) {
this.position = position;
}
public int getPosition() {
return this.position;
}
}
我得到了结果:
10 12 9 8 6 6 5 4 2 1 16 16 18 19 19 19 19 19 19 19
为什么呢?我想得到:
1 2 3 4 ...... 20
是否有任何选项可以改进此代码段?
答案 0 :(得分:1)
试试这段代码;)
import java.util.ArrayList;
import java.util.List;
public class ogr
{
public static void main(String[] args) throws InterruptedException {
final PositionHolder holder = new PositionHolder();
final List<Integer> data = new ArrayList<Integer>();
for (int i = 0; i < 20; i++) {
holder.setPosition(i);
Thread t = new Thread() {
@Override
public void run() {
data.add(holder.getPosition());
}
};
t.start();
t.join();
}
for (int i : data) {
System.out.println(i);
}
}
}
class PositionHolder
{
int position = 0;
public void setPosition(int position) {
this.position = position;
}
public int getPosition() {
return this.position;
}
}
答案 1 :(得分:0)
您不能保证holder.getPosition()将获得您使用holder.setPosition(i)设置的相同位置值,因为getHolder调用是不同线程的一部分并由多个线程调用。这是因为您在所有线程中共享相同的PlaceHolder。如果你想获得你想要的输出,我会建议为每个线程使用不同的PlaceHolder实例。
import java.util.ArrayList;
import java.util.List;
public class TaskExample {
public static void main(String[] args) throws InterruptedException {
final List<Integer> data = new ArrayList<Integer>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 20; i++) {
// Create new instance
final PositionHolder holder = new PositionHolder(i);
Thread t = new Thread() {
@Override
public void run() {
data.add(holder.getPosition());
}
};
t.start();
threads.add(t);
for (Thread thread : threads) {
thread.join();
}
for(int i : data){
System.out.println(i);
}
}
class PositionHolder {
private int position = 0;
public PositionHolder(int position) {
this.position = position;
}
public int getPosition() {
return this.position;
}
}`
答案 2 :(得分:0)
如果没有像join()
这样的同步机制,就无法保证线程的执行顺序(参见Fincio提出的代码)。
您正在多次获得相同的数字,因为您对所有线程使用相同的PositionHolder
对象,因此,变量position
会被您启动的每个线程修改。试图用Object而不是int来做同样的事情可能会让你ConcurrentAccessException
。为了避免这种情况,每个线程都应该有自己的PositionHolder
实例(就像Saket提供的代码一样)。但即便如此,也无法保证线程的执行顺序。
答案 3 :(得分:0)
import java.util.ArrayList;
import java.util.List;
public class ogr{
public static void main(String[] args) throws InterruptedException {
ArrayList<PositionHolder> holders=new ArrayList<PositionHolder>();
final PositionHolder holder = new PositionHolder();
final List<Integer> data = new ArrayList<Integer>();
for (int i = 0; i < 20; i++) {
Thread t = new Thread() {
@Override
public void run() {
data.add(getSetPosition());
}
};
holders.add(holder)
t.start();
}
for (Thread thread : threads) {
thread.join();
}
SortByPosition(holders); //you can implement this easy by sorting arraylist by their positions
for (int i : data) {
System.out.println(i);
}
}
}
class PositionHolder{
static int staticPosition=0;
int position = 0;
public int synchronized getSetPosition() {
this.position = staticPosition++;
return position;
}
// public void setPosition(int position) {
// this.position = position;
// }
public int getPosition() {
return this.position;
}
}