Java 多线程竞速模拟问题
Java Multi-Thread racing simulation issue
我有一个代表赛车的 class,在它里面我有一个方法 每当汽车通过 1000 int 检查点时打印到控制台。
在 运行 重写中,我调用了该方法,并且它对我创建的每辆汽车的 运行 都不同,但我认为我弄错了,因为结果每次都在变化(它需要保持不变,因为有些车更快,所以我不认为这些车在不同的线程中移动。
public class RacingCar extends Thread{
private String model;
private int speed;
public RacingCar(){}
public RacingCar(String model, int speed){
this.start();
this.model = model;
this.speed = speed;
}
public void go(){
int trackLength=5000;
int checkPointPassed=0;
for(int i=0;i<trackLength;i+=speed){
if(checkPointPassed*1000<i){
checkPointPassed++;
System.out.println(this.model+" has passed the "+checkPointPassed+"th check point");
}
}
}
@Override
public void run() {
go();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}}
测试人员(主要):
public class Tester {
public static void main(String[] args) {
new RacingCar("Honda", 6);
new RacingCar("Lamborghini", 100);
new RacingCar("McLaren", 8);
}}
嗯,这里:
public RacingCar(String model, int speed){
this.start();
this.model = model;
this.speed = speed;
}
您在对象完全创建之前使用 this.start()
,这很糟糕。
第二件事,你已经在线程 运行 之后分配参数(意味着非确定性行为)。
一般来说,您应该在构造函数之外创建对象并运行它。
您应该将睡眠移动到循环内,并在启动线程之前完全创建 RacingCars。
public class RacingCar extends Thread {
private String model;
private int speed;
public RacingCar(String model, int speed) {
this.model = model;
this.speed = speed;
}
@Override
public void run() {
try {
go();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
private void go() throws InterruptedException {
int trackLength = 5000;
int checkPointPassed = 0;
for(int i = 0; i < trackLength; i += speed) {
if(checkPointPassed * 1000 < i) {
checkPointPassed++;
System.out.println(this.model + " has passed the " + checkPointPassed + "th check point");
}
Thread.sleep(10);
}
}
}
public class Tester {
public static void main(String[] args) {
RacingCar honda = new RacingCar("Honda", 6);
RacingCar lamborghini = new RacingCar("Lamborghini", 100);
RacingCar mcLaren = new RacingCar("McLaren", 8);
honda.start();
lamborghini.start();
mcLaren.start();
}
}
(请注意,即使您这样做,也无法严格保证线程的调度顺序 运行。)
我有一个代表赛车的 class,在它里面我有一个方法 每当汽车通过 1000 int 检查点时打印到控制台。
在 运行 重写中,我调用了该方法,并且它对我创建的每辆汽车的 运行 都不同,但我认为我弄错了,因为结果每次都在变化(它需要保持不变,因为有些车更快,所以我不认为这些车在不同的线程中移动。
public class RacingCar extends Thread{
private String model;
private int speed;
public RacingCar(){}
public RacingCar(String model, int speed){
this.start();
this.model = model;
this.speed = speed;
}
public void go(){
int trackLength=5000;
int checkPointPassed=0;
for(int i=0;i<trackLength;i+=speed){
if(checkPointPassed*1000<i){
checkPointPassed++;
System.out.println(this.model+" has passed the "+checkPointPassed+"th check point");
}
}
}
@Override
public void run() {
go();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}}
测试人员(主要):
public class Tester {
public static void main(String[] args) {
new RacingCar("Honda", 6);
new RacingCar("Lamborghini", 100);
new RacingCar("McLaren", 8);
}}
嗯,这里:
public RacingCar(String model, int speed){
this.start();
this.model = model;
this.speed = speed;
}
您在对象完全创建之前使用 this.start()
,这很糟糕。
第二件事,你已经在线程 运行 之后分配参数(意味着非确定性行为)。
一般来说,您应该在构造函数之外创建对象并运行它。
您应该将睡眠移动到循环内,并在启动线程之前完全创建 RacingCars。
public class RacingCar extends Thread {
private String model;
private int speed;
public RacingCar(String model, int speed) {
this.model = model;
this.speed = speed;
}
@Override
public void run() {
try {
go();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
private void go() throws InterruptedException {
int trackLength = 5000;
int checkPointPassed = 0;
for(int i = 0; i < trackLength; i += speed) {
if(checkPointPassed * 1000 < i) {
checkPointPassed++;
System.out.println(this.model + " has passed the " + checkPointPassed + "th check point");
}
Thread.sleep(10);
}
}
}
public class Tester {
public static void main(String[] args) {
RacingCar honda = new RacingCar("Honda", 6);
RacingCar lamborghini = new RacingCar("Lamborghini", 100);
RacingCar mcLaren = new RacingCar("McLaren", 8);
honda.start();
lamborghini.start();
mcLaren.start();
}
}
(请注意,即使您这样做,也无法严格保证线程的调度顺序 运行。)