【Java多线程】两个线程猜数字

一、作业要求:

1、用两个线程玩猜数字游戏,第一个线程负责随机给出1-100之间的一个整数,
第二个线程负责猜出这个数。
2、要求每当第二个线程给出自己的猜测之后, 第一个线程都会提示“猜小了”、“猜大了”或“猜对了”。
3、猜数之前,要求第二个线程要等到第一个线程设置好要猜的数。
4、第一个线程设置好猜测数之后,两个线程还要互相等待,其原则是,第二个线程给出自己的猜测后,等待第一个线程给出的提示; 第一个线程给出提示后,等待第二个线程给出猜测,如此进行,直到第二个线程给出正确的出猜测后, 两个线程进入死亡状态。

二、思路:
  • 线程一的作用
    • 给出随机数random
    • 判断猜测数字guessnumberrandom大小关系,并给出判断
  • 线程二的作用
    • 猜测数字
  • 为了实现线程一与线程二之间的联系,采用线程通信的方式。(wait和notify)
三、代码
import java.util.Scanner;

/*
* 4、用两个线程玩猜数字游戏,第一个线程负责随机给出1-100之间的一个整数,
* 第二个线程负责猜出这个数。要求每当第二个线程给出自己的猜测之后,
* 第一个线程都会提示“猜小了”、“猜大了”或“猜对了”。猜数之前,
* 要求第二个线程要等到第一个线程设置好要猜的数。第一个线程设置好猜测数之后,
* 两个线程还要互相等待,其原则是,第二个线程给出自己的猜测后,等待第一个线程给出的提示;
* 第一个线程给出提示后,等待第二个线程给出猜测,如此进行,直到第二个线程给出正确的出猜测后,
* 两个线程进入死亡状态。
*/
//线程1:给1-100的随机数 判断
//线程2:猜
public class GuessNumber {
  public static void main(String[] args) {
  	Num n = new Num();
  	GuessThread guess = new GuessThread(n);
  	JudgeThread judge = new JudgeThread(n);
  	judge.start();
  	guess.start();
  }
}
// Num类完成线程之间的同步
class Num {
  int number;// 保存猜测的数
  boolean first = true;
  boolean stop = false;
}

class GuessThread extends Thread {
  Num num;
  public GuessThread(Num num) {
  	this.num = num;
  }
  @Override
  public void run() {
  	Scanner sc = new Scanner(System.in);
  	while (true) {
  		try {
  			synchronized (num) {
  				if (num.first) {// 如果是第一次执行
  					num.wait();
  				} else if (num.stop) {
  					System.out.println("猜数结束");
  					return;
  				} else {
  					System.out.println("请输入猜测的数(1-100):");
  					int guess = sc.nextInt();
  					// 猜数结束就需要等待,判断线程
  					num.number = guess;
  					num.notify();
  					num.wait();
  				}
  			}
  		} catch (Exception e) {
  			e.printStackTrace();
  		}
  	}
  }
}
//判断线程
class JudgeThread extends Thread {
  Num num;
  public JudgeThread(Num num) {
  	this.num = num;
  }
  @Override
  public void run() {
  	int random = 0;
  	while (true) {
  		try {
  			synchronized (num) {
  				if (num.first) {
  					random = (int) (Math.random() * 100 + 1);
  					System.out.println("随机数已产生:" + random);
  					num.first = false;
  					num.notify();
  					num.wait();
  				} else {
  					// 判断过程
  					if (num.number < random) {
  						System.out.println("猜小了!");
  					} else if (num.number > random) {
  						System.out.println("猜大了!");
  					} else {
  						System.out.println("猜对了!");
  						num.stop = true;
  						num.notify();// 猜对结束之前
  						return;
  					}
  					num.notify();
  					num.wait();
  				}
  			}
  		} catch (Exception e) {
  			e.printStackTrace();
  		}
  	}
  }
}

以上是人为去输入猜测的数字,下面是自动猜数的一些代码。

//自动猜数字:利用线程通信完成
public class GuessNumber2 {
  public static void main(String[] args) {
  	Num2 num2 = new Num2();
  	GuessNum gn = new GuessNum(num2);
  	JudgeNum jn = new JudgeNum(num2);
  	jn.start();
  	gn.start();
  }
}
class Num2 {
  int number;
  int flag = 0;// 用于比较猜测数字的大小:1:猜数大 0:猜对 -1:猜数小
  boolean first = true;// 判断是否是第一次猜数
  boolean stop = false;// 判断是否猜对
}
class GuessNum extends Thread {
  Num2 num2;
  String name = "GuessNumber-->";
  public GuessNum(Num2 num2) {
  	this.num2 = num2;
  }
  @Override
  public void run() {
  	// Scanner sc = new Scanner(System.in);
  	int max = 100;
  	int min = 1;
  	int guess = (int) (Math.random() * (max - min + 1) + 1);
  	while (true) {// 在判断正确以前需要循环
  		try {
  			synchronized (num2) {
  				if (num2.first) {
  					num2.wait();
  				} else if (num2.stop) {
  					System.out.println("---猜数结束---");
  					return;
  				} else {
  					// System.out.println("请输入猜测的数(1-100):");
  					// int guess = sc.nextInt();
  					// 猜数结束就需要等待,判断线程
  					switch (num2.flag) {// 根据flag的判断,逐渐缩小范围
  					case 0:// flag为0
  						break;
  					case 1:// 猜数大
  						if (max > guess)
  							max = guess;// 最大值用前一次的guess替代
  						guess = (int) (Math.random() * (max - min + 1) + min);
  						break;
  					case -1:
  						if (min < guess)
  							min = guess;// 最小值用前一次的guess替代
  						guess = (int) (Math.random() * (max - min + 1) + min);
  						break;
  					}
  					num2.number = guess;
  					Thread.sleep(1000);// 暂停1秒
  					System.out.println();
  					System.out.println(name + guess);
  					System.out.println("max=" + max + " min=" + min);
  					num2.notify();
  					num2.wait();
  				}
  			}
  		} catch (Exception e) {
  			e.printStackTrace();
  		}
  	}
  }
}

class JudgeNum extends Thread {
  Num2 num2;
  String name;
  public JudgeNum(Num2 num2) {
  	this.num2 = num2;
  	this.name = "JudgeNumber-->";
  }
  @Override
  public void run() {
  	int random = 0;
  	while (true) {// 在判断正确以前需要循环
  		try {
  			synchronized (num2) {// 同步
  				if (num2.first) {// 当first为true
  					random = (int) (Math.random() * 100 + 1);
  					System.out.println(name + "随机数已产生:" + random);// 产生随机数
  					num2.first = false;
  					num2.notify();// 先唤醒
  					num2.wait();// 再等待
  				} else {
  					Thread.sleep(1000);
  					switch (judge(random)) {
  					case 1:
  						System.out.println(name + "猜大了!");
  						num2.flag = 1;
  						break;
  					case -1:
  						System.out.println(name + "猜小了!");
  						num2.flag = -1;
  						break;
  					case 0:
  						System.out.println(name + "猜对了!");
  						num2.flag = 0;
  						num2.stop = true;// 把stop设置成true
  						num2.notify();
  						return;
  					}
  					num2.notify();
  					num2.wait();
  				}
  			}
  		} catch (Exception e) {
  			e.printStackTrace();
  		}
  	}
  }
  int judge(int jnum) {
  	int result = 0;
  	if (num2.number > jnum) {
  		result = 1;
  	} else if (num2.number < jnum) {
  		result = -1;
  	}
  	return result;
  }
}
四、总结
  • 多线程的相关内容不是很难,但是需要根据不同的情况去设置线程就相对比较复杂了。
  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行走中思考

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值