实验目的:
学习使用Thread类创建线程,以及怎样处理线程同步
main.java
public class Main {
public static void main(String[] args) {
Number number=new Number() ;
number.giveNumberThread.start();
number.guessNumberThread.start();
}
}
Number.java
public class Number implements Runnable{
final int SMALLER=-1,LARGER=1,SUCCESS=8;
int realNumber,guessNumber,min=0,max=100,message=SMALLER;
boolean pleaseGuess=false,isGiveNumber=false;
Thread giveNumberThread,guessNumberThread;
Number() {
giveNumberThread=new Thread(this);
guessNumberThread=new Thread(this);
}
public void run(){
for(int count=1;true;count++){
setMessage(count);
if(message==SUCCESS)
return;
}
}
public synchronized void setMessage(int count){
if(Thread.currentThread()==giveNumberThread&&isGiveNumber==false){
realNumber=(int)(Math.random()*100)+1;
System.out.println("随机给你一个1至100之间的数,猜猜是多少?");
isGiveNumber=true;
pleaseGuess=true;
}
if(Thread.currentThread()==giveNumberThread){
while(pleaseGuess==true)
try{
wait();//让出cpu使用权,让另一个线程开始猜数
}
catch(InterruptedException e){}
if(realNumber>guessNumber)
{
message=SMALLER;
System.out.println("你猜小了");
}
else if(realNumber<guessNumber){
message=LARGER;
System.out.println("你猜大了");
}
else{
message=SUCCESS;
System.out.println("恭喜,你猜对了");
}
pleaseGuess=true;
}
if(Thread.currentThread()==guessNumberThread&&isGiveNumber==true){
while(pleaseGuess==false)
try{
wait();
}
catch(InterruptedException e){}
if(message==SMALLER){
min=guessNumber;
guessNumber=(min+max)/2;
System.out.println("我第"+count+"次猜这个数是:"+guessNumber);
}
else if(message==LARGER){
max=guessNumber;
guessNumber=(min+max)/2;
System.out.println("我第"+count+"次猜这个数是:"+guessNumber);
}
pleaseGuess=false;
}
notifyAll();/*notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。两者的最大区别在于:
notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。
notify则文明得多他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。
*/
}
}
运行结果:
实验感想:
对于Thread(Runnable target)构造方法创建的线程,轮到它来享用CPU资源时,目标就会自动调用借口中的run(方法)