当前位置: 首页 > news >正文

Java面试题(六)多线程经典编程题

经典的多线程编程题

  • 猜数字游戏
  • 键盘输入练习
  • 3个线程轮流打印ABC
  • 多窗口买票

猜数字游戏

题目说明:有2个线程,第一个线程A随机一个100内的数,第2个线程B来猜,B每次猜一个数后A会判断,如果猜对了程序结束,如果猜大了,或者猜小了,就要缩小猜的范围继续猜;

例如:
A线程随机一个数:66
B线程第一次猜44
A线程说猜小了,继续猜
B线程此时猜的范围就是44-100以内
然后B线程继续猜88
A线程说猜大了,继续猜
B线程此时才的范围就是44-88
然后同上继续,直到最后猜中为止

//先准备一个实体类
public static class Guess{

    //1=猜大了,2=猜小了,3=猜对了
    private Integer isBigOrSmall = 3;
    //猜的数
    private Integer guessNum;
    //随机数
    private Integer randomNum;
    //每次猜数的边界值
    private Integer max = 100;
    private Integer min = 1;

	//get set
}
public static void main(String[] args) {

    Guess guess = new Guess();
    //A线程随机一个1-100内的数
    Integer randomNum = (int)(Math.random() * guess.getMax()) + guess.getMin();
    guess.setRandomNum(randomNum);

    System.out.println("随机给你一个数1-100的数,看你能猜出来吗?" + randomNum);

    Random random = new Random();
	//B线程第一次随机猜的一个数1-100
    Integer guessNum = random.nextInt(guess.getMax())+guess.getMin();
    guess.setGuessNum(guessNum);

    Thread t1 = new Thread(){
        @Override
        public void run(){
            int count = 1;
            while (true){
                if(guess.getIsBigOrSmall() == 1){
                    Integer guessNum = (int)(Math.random() * (guess.getGuessNum() - guess.getMin())) + guess.getMin();
                    guess.setGuessNum(guessNum);
                }else if(guess.getIsBigOrSmall() == 2){
                    Integer guessNum = (int)(Math.random() * (guess.getMax() - guess.getGuessNum())) + guess.getGuessNum();
                    guess.setGuessNum(guessNum);
                }
                System.out.println("我第" + count + "次猜这个数是:" + guess.getGuessNum() + "---猜的范围是" + guess.getMin() + "-" + guess.getMax());
                count ++;
                try {
                    sleep(2001);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    Thread t2 = new Thread(){
        @Override
        public void run(){
            while (true){
                if(guess.getGuessNum() != null){
                    if(guess.getGuessNum() > randomNum){
                        System.out.println("你猜大了");
                        guess.setIsBigOrSmall(1);
                        guess.setMax(guess.getGuessNum());
                    }else if(guess.getGuessNum() < randomNum){
                        System.out.println("你猜小了");
                        guess.setIsBigOrSmall(2);
                        guess.setMin(guess.getGuessNum());
                    }else{
                        System.out.println("恭喜你,猜对了!");
                        guess.setIsBigOrSmall(3);
                        System.exit(0);
                    }
                    try {
                        sleep(2010);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    };
    t1.start();
    t2.start();
}

在这里插入图片描述

键盘输入练习

线程A每次在控制台给出a-z任意字符,然后在控制台输入对应的字符,B线程判断是否输入正确,正确就得分+1,错误得分-1;注意只有在控制台输入后,B线程才能判断,等B判断完之后A线程才能给出字符

//准备一个答案类
public static class Answer{

	//题目给出的字符
    private char subject;
    //当前得分
    private int score = 0;

	//get set
}
public static void main(String[] args) {
    System.out.println("键盘输入练习(输入#结束程序)");
    System.out.println("输入显示的字母(回车)\n");

    char startChar = 'a',endChar = 'z';
    Answer answer = new Answer();
    //从a开始输入
	answer.setSubject(startChar);
    Thread t1 = new Thread(){
        @Override
        public void run() {

            char c = startChar;
            while (true){
                System.out.println("显示的字符:" + c);
                LockSupport.park();

                c = (char) (c + 1);
                if(c > endChar){
                    c = endChar;
                }
                answer.setSubject(c);
            }
        }
    };

    Scanner sc = new Scanner(System.in);
    Thread t2 = new Thread(){
        @Override
        public void run() {

            while (true){
                char c = sc.next().charAt(0);
                if(answer.getSubject() == c){
                    answer.setScore(answer.getScore() + 1);
                    System.out.println("输入对了,目前分数:" + answer.getScore());
                }else{
                    answer.setScore(answer.getScore() - 1);
                    System.out.println("输入错了,目前分数:" + answer.getScore());
                }
                LockSupport.unpark(t1);
                if(c == '#'){
                    System.out.println("答题结束:最终得分:" + answer.getScore());
                    System.exit(0);
                }
            }
        }
    };
    t1.start();
    t2.start();
}

在这里插入图片描述

3个线程轮流打印ABC

3个线程轮流打印ABC,可以通过锁来实现

public class ThreadDemo {

	//锁
    private static Lock lock = new ReentrantLock();

    //根据余数判断该哪个线程打印了
    private static int remainder = 0;
	
	//第一个线程
    static class ThreadFirst extends Thread{
        @Override
        public void run(){
            for(int i=0;i<10;) {
                lock.lock();
                try {
                    while(remainder % 3 == 0) {
                        System.out.println("线程1拿到锁:A");
                        remainder++;
                        i++;
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }


        }
    }

	//第二个线程
    static class ThreadSecond extends Thread{
        @Override
        public void run(){
            for(int i=0;i<10;) {
                lock.lock();
                try {
                    while(remainder % 3 == 1) {
                        System.out.println("线程2拿到锁:B");
                        remainder++;
                        i++;
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }

        }
    }

	//第三个线程
    static class ThreadThird extends Thread{
        @Override
        public void run(){

            for(int i=0;i<10;) {
                lock.lock();
                try {
                    while(remainder % 3 == 2) {
                        System.out.println("线程3拿到锁:C");
                        remainder++;
                        i++;
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    public static void main(String[] args) {
        new ThreadFirst().start();
        new ThreadSecond().start();
        new ThreadThird().start();
    }
}

多窗口买票

例如ABC3个线程卖100张票,卖完为止

public class SellTicket {

    static class Window implements Runnable{

        private static int ticket = 100;
        @Override
        public void run() {
            while (true){

                try {
                    Thread.sleep(500L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (this){
                    if (ticket <= 0) {
                        break;
                    }
                    System.out.println(Thread.currentThread().getName() + "卖了第" + ticket + "张票");
                    ticket--;
                }
            }
        }
    }

    public static void main(String[] args) {
        Window w = new Window();

        Thread w1 = new Thread(w,"窗口1");
        Thread w2 = new Thread(w,"窗口2");
        Thread w3 = new Thread(w,"窗口3");
        w1.start();
        w2.start();
        w3.start();

    }
}

在这里插入图片描述

相关文章:

  • js 正则
  • 分布式锁
  • qt实现的pdf阅读器(二)--XpdfReader在linux下的编译
  • 视频号直播间首次突破1万人
  • 一款强大的免费开源的基于流量分析的扫描器结合不同场景的实际使用与漏-洞及木-马发现实践
  • 让人恶心的多线程代码,性能怎么优化?
  • 关于我转行嵌入式的那些事
  • 搞定 Redis 数据存储原理,别只会 set、get 了
  • 当云原生成为一种显学,对象存储和数据湖如何顺势而为
  • 计算机网络~物理层
  • Redis 多路复用
  • ICV:车载毫米波雷达市场有望在2023年突破45亿美元!
  • 【数据库】简答题知识点
  • Linux5.4.0内存分配器核心代码解析
  • SpringBoot 结合 MyBatis-Plus 配置多数据源以及结合 p6spy 打印 SQL 日志
  • PPCNN
  • Windows tensorflow、keras虚拟环境搭建记录(使用conda和mamba)
  • Canvas 从进阶到退学
  • 376. 机器任务——最小点覆盖+匈牙利算法
  • [第十二届蓝桥杯/java/算法]F——时间显示