1. 双线程猜数字
用两个线程玩猜数字游戏,第一个线程负责随机给出1~10之间的一个整数,第二个线程负责猜出这个数。
要求:每当第二个线程给出自己的猜测后,第一个线程都会提示“猜小了”、“猜 大了”或“猜对了”。猜数之前,要求第二个线程要等待第一个线程设置好 要猜测的数。
第一个线程设置好猜测数之后,两个线程还要相互等待,其原 则是:第二个线程给出自己的猜测后,等待第一个线程给出的提示;
第一个 线程给出提示后,等待第二个线程给出猜测,如此进行,直到第二个线程给 出正确的猜测后,两个线程进入死亡状态。
import java.util.Map;
/**
* 自定义随机数类
*/
public class RandomNum {
private int randomNum ; // 随机数
private int guessNum = 50 ;// 初始化猜测数
// 表示线程的不同状态 wait(true) notifyAll(false)
private boolean flag = false ;
// 表示猜测结果 1 表示 猜对了 0 表示 没猜对
private int bigOrSmall ;
private String msg ; // 提示信息
// 构造方法 负责生成随机数
public RandomNum() {
randomNum = (int)(Math.random() * 100 + 1);
}
public int getRandomNum() {
return randomNum;
}
public void setRandomNum(int randomNum) {
this.randomNum = randomNum;
}
public int getGuessNum() {
return guessNum;
}
public void setGuessNum(int guessNum) {
this.guessNum = guessNum;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public int getBigOrSmall() {
return bigOrSmall;
}
public void setBigOrSmall(int bigOrSmall) {
this.bigOrSmall = bigOrSmall;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "RandomNum{" +
"randomNum=" + randomNum +
'}';
}
}
import javax.crypto.spec.PSource;
/**
* 线程1 负责生成随机数 并给出提示
*/
public class Thread1 implements Runnable{
private RandomNum randomNum ;
public Thread1(RandomNum randomNum) {
this.randomNum = randomNum;
}
@Override
public void run() {
synchronized (Object.class){
while (true){
// true 表示wait 说明线程2正在猜数字 这里就继续等待
if (randomNum.isFlag()){
try {
Object.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 只有flag = false 的时候才会执行到这里
// 开始判断线程2 是否猜对?
if (randomNum.getGuessNum() < randomNum.getRandomNum()){
System.out.println("线程1===> 猜小了");
System.out.println("随机数===> " + randomNum.getRandomNum());
System.out.println("你猜的是===> " + randomNum.getGuessNum());
System.out.println("继续猜吧...");
// 设置参数
randomNum.setBigOrSmall(0); // 没猜对
randomNum.setFlag(true); //
Object.class.notifyAll(); //
}else if (randomNum.getGuessNum() > randomNum.getRandomNum()){
System.out.println("线程1===> 猜大了");
System.out.println("随机数===> " + randomNum.getRandomNum());
System.out.println("你猜的是===> " + randomNum.getGuessNum());
System.out.println("继续猜吧...");
// 设置参数
randomNum.setBigOrSmall(0); // 没猜对
randomNum.setFlag(true); //
Object.class.notifyAll(); //
}else {
System.out.println("线程1===> 猜对了");
System.out.println("随机数===> " + randomNum.getRandomNum());
System.out.println("你猜的是===> " + randomNum.getGuessNum());
randomNum.setBigOrSmall(1);
// 退出循环
break;
}
}
}
}
}
/**
* 线程2 负责 猜数字
*/
public class Thread2 implements Runnable {
private RandomNum randomNum ;
public Thread2(RandomNum randomNum) {
this.randomNum = randomNum;
}
@Override
public void run() {
synchronized (Object.class){
int start = 1 ;
int end = 100 ;
while (randomNum.getBigOrSmall() == 0){
if (randomNum.isFlag() == false){
try {
Object.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// flag = true 时 才会执行到这里
// 使用二分法查找
int mid = (start + end) / 2 ;
if (mid == randomNum.getRandomNum()){
randomNum.setBigOrSmall(1); // 猜对了
randomNum.setGuessNum(mid);
Object.class.notifyAll();
}else if (mid > randomNum.getRandomNum()){
randomNum.setGuessNum(mid);
end = mid - 1;
randomNum.setFlag(false);
Object.class.notifyAll();
}else {
randomNum.setGuessNum(mid);
start = mid + 1;
randomNum.setFlag(false);
Object.class.notifyAll();
}
if (start > end){
randomNum.setMsg("没猜出来");
}
}
}
}
}
public class DoubleThreadGuessNum {
public static void main(String[] args) {
/**
* 1. 双线程猜数字
* 用两个线程玩猜数字游戏,第一个线程负责随机给出1~100之间的一个整数,第二个线程负责猜出这个数。
* 要求:每当第二个线程给出自己的猜测后,第一个线程都会提示“猜小了”、“猜 大了”或“猜对了”。
* 猜数之前,要求第二个线程要等待第一个线程设置好 要猜测的数。
* 第一个线程设置好猜测数之后,两个线程还要相互等待,其原 则是:第二个线程给出自己的猜测后,等待第一个线程给出的提示;
* 第一个 线程给出提示后,等待第二个线程给出猜测,如此进行,直到第二个线程给 出正确的猜测后,两个线程进入死亡状态。
*
* 如何获取线程状态?
* wait()
* notifyAll()
* 两个线程 都需要随机数 线程1负责生成正确答案 线程2负责随机的去猜
*
* 共享的随机数类中 设置一些 结果提示“猜小了”、“猜大了”或“猜对了”
*
*/
RandomNum randomNum = new RandomNum();
Thread1 thread1 = new Thread1(randomNum);
Thread2 thread2 = new Thread2(randomNum);
Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2);
t1.start();
t2.start();
}
}
2. 写两个线程,一个线程打印1~52,另一个线程打印字母A~Z。打印顺序为12A34B56C........5152Z。要求用线程间的通信
public class PrintNum implements Runnable{
@Override
public void run() {
synchronized (Object.class){
for (int i = 1; i <= 52 ; i++) {
// 12A34B56C78D
System.out.print(i);
if (i % 2 == 0 ){
Object.class.notifyAll(); // 叫醒别人
try {
Object.class.wait(); // 自己睡觉
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public class PrintZimu implements Runnable{
@Override
public void run() {
synchronized (Object.class){
for (char i = 'A'; i <= 'Z' ; i++) {
System.out.print(i);
Object.class.notifyAll();
try {
Object.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintNumZimu {
public static void main(String[] args) {
/**
* 2. 写两个线程,一个线程打印1~52,另一个线程打印字母A~Z。
* 打印顺序为12A34B56C........5152Z。
* 要求用线程间的通信
*/
PrintNum printNum = new PrintNum();
PrintZimu printZimu = new PrintZimu();
Thread t1 = new Thread(printNum);
Thread t2 = new Thread(printZimu);
t1.start();
t2.start();
}
}