多线程练习,两个对象,随机提出问题和随机给出答案。
//提问者类
package com.konghao.talk2;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Asker implements Runnable {
private String name; //提问者姓名
private boolean isAsk; //是否提问的标记
private List<String> questions = new ArrayList<String>(); //提问列表
private String question;//当前问题
private BufferedReader buf = null; //文本输入流
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public static Random ran = new Random();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isAsk() {
return isAsk;
}
public void setAsk(boolean isAsk) {
this.isAsk = isAsk;
}
public Asker(String name) {
super();
this.name = name;
this.isAsk = false;
}
@Override
public void run() {
//运行run方法时,读取文件中的questions
try {
buf = new BufferedReader(new FileReader("E:"
+ "\\JAVA\\Temp\\questions.txt"));
String str = null;
while((str = buf.readLine())!=null){
questions.add(str);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//循环提问
for (int i = 0; i < 20; i++) {
ask();
}
}
//提问方法
public void ask(){
synchronized (this) {
int index = ran.nextInt(questions.size());
if(!this.isAsk){ //如果没有提问,即 isAsk 为false,就从问题列表中随机抽取问题进行提问
String qstr = questions.get(index);
System.out.println(this.name+":"+qstr);
this.setQuestion(qstr);//当前问题传入set方法
this.setAsk(true); //将isAsk 设置为true
this.notify(); //唤醒其他线程
try {
Thread.sleep(1000);
this.wait(); //挂起
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//回答者类
package com.konghao.talk2;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Answer implements Runnable{
private String name; //回答者姓名
private List<String> answers = new ArrayList<String>(); //答案列表
private Asker asker; //提问者
private BufferedReader buf = null; //文件输入流
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Answer(String name,Asker asker) {
super();
this.name = name;
this.asker = asker;
}
@Override
public void run() {
/**
* @author Lang JP
* 在run()运行的时候初始化answers列表,从文本文件中读出字符串,并add()进List
*/
try {
buf = new BufferedReader(new FileReader("E:"
+ "\\JAVA\\Temp\\answers.txt"));
String str = null;
while((str = buf.readLine())!=null){
answers.add(str);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
buf.close(); //关闭输入流
} catch (IOException e) {
e.printStackTrace();
}
}
while(true){
/**
* 设置为死循环,可将Answer线程设置为后台线程,只要Asker停止,Answer就会停止。
*/
this.talk();
}
}
//回答方法
public void talk(){
synchronized (asker) {//用asker做同步
int index = Asker.ran.nextInt(answers.size()); //随机数,用于随机从List中抽取答案
if(asker.isAsk()){ //如果已经提问,即isAsk为true;
if(asker.getQuestion().equals("嘿嘿")){
System.out.println(this.name+":嘿你大爷。");
}else{
System.out.println(this.name+":"+answers.get(index));
}
asker.setAsk(false); //将是否提问设置为false
asker.notify(); //唤醒用asker做同步的其他线程,即 Asker
try {
Thread.sleep(1000);
asker.wait(); //挂起
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
asker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//测试类
package com.konghao.talk2;
public class Test {
public static void main(String[] args) {
Asker asker = new Asker("大傻子一号");
Answer ans = new Answer("傻子二号", asker);
Thread atk = new Thread(asker);
Thread ats = new Thread(ans);
ats.setDaemon(true);
atk.start();
ats.start();
}
}