1. 题目
实现一个竞拍抢答程序:要求设置3个抢答者(3个线程),而后同时发出抢答指令,并为抢答成功者给出成功提示,为未抢答者给出失败提示。
2. 分析
1)3个抢答者使用3个线程,因为要为每一个抢答者给出提示,这个提示可以理解成线程的返回结果,故我们这里使用Callable接口实现线程。
2)3个线程都会执行,只是先后顺序不同。在这里,我们设置一个标志为flag在第一次运行时改变其值即可。
3. 代码
1)MyThread.java
import java.util.concurrent.Callable;
public class MyThread implements Callable{
private boolean flag=false; //用于记录是否抢答成功
@Override
public String call() throws Exception {
synchronized (this){
if(this.flag==false){
this.flag=true;
return Thread.currentThread().getName()+"抢答成功";
}else{
return Thread.currentThread().getName()+"抢答失败";
}
}
}
}
在返回结果的时候,我们需要利用同步机制来防止出现flag和返回结果不对应的情况。
2) Answer0903.java
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Answer0903 {
public static void main(String args[]) throws ExecutionException, InterruptedException {
MyThread my=new MyThread();
FutureTask<String> taskA=new FutureTask<>(my);
FutureTask<String> taskB=new FutureTask<>(my);
FutureTask<String> taskC=new FutureTask<>(my);
Thread.sleep(2000);
System.out.println("抢答开始");
new Thread(taskA,"抢答者A").start();
new Thread(taskB,"抢答者B").start();
new Thread(taskC,"抢答者C").start();
System.out.println(taskA.get());
System.out.println(taskB.get());
System.out.println(taskC.get());
}
}
运行结果:(具有不确定性)
在第一个抢占到资源的线程中,首次进入到call()方法,因为flag默认值为false,修改了flag的值为true,并返回抢答成功。后面抢占到资源的线程,因为flag被更改为true,返回值均为抢答失败。成功实现。