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

news2024/11/20 3:25:45

经典的多线程编程题

  • 猜数字游戏
  • 键盘输入练习
  • 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();

    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工具在接口测试中发挥什么样的作用?

接口测试究竟是什么&#xff1f;为什么要用接口测试&#xff1f;它有哪些工具呢&#xff1f;这一连串的问题敲击着我们&#xff0c;请带着这些问题&#xff0c;在本文中寻找答案&#xff0c;我将为您打开接口测试的大门。 1 初探接口测试 接口测试是什么。它检查数据的交换&…

从《我要投资》,看藏在“对立面”里的创业正解

文|智能相对论 作者|青月 六位07届的快乐男声选手在象山体验养鹅&#xff0c;意外出圈&#xff1b;随后播出的09届超女的怀旧综艺却热度一般&#xff0c;可见只有单纯的情怀消费并不能保证节目的口碑&#xff0c;只有建立在准确的节目定位与恰当的价值输出基础上&#xff0c;…

面试必备:从常见的存储引擎到混淆的锁分类,请上车

今天我们来总结一下MyISAM和InnoDB引擎下锁的种类及使用方法。 MySQL的四大常见存储引擎 谈到MyISAM和InnoDB了我们先来了解一下什么是存储引擎吧。MySQL中的数据用各种不同的技术存储在文件&#xff08;或者内存&#xff09;中&#xff0c;这些技术中的每一种技术都使用不同…

m基于贝叶斯理论的超分辨率重构算法matlab仿真,对比Tikhonov重构算法

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 超分辨率(Super-Resolution)通过硬件或软件的方法提高原有图像的分辨率&#xff0c;通过一系列低分辨率的图像来得到一幅高分辨率的图像过程就是超分辨率重建。超分辨率成像&#xff08;SR-imagi…

一个内核oops问题的分析及解决

最近在调试设备时&#xff0c;遇到了一个偶发的开机死机问题。通过查看输出日志&#xff0c;发现内核报告了oops错误&#xff0c;如下所示&#xff08;中间省略了部分日志&#xff0c;以......代替&#xff09;&#xff1a; Unable to handle kernel NULL pointer dereference…

YOLOV7学习记录之训练过程

在前面学习YOLOV7的过程中&#xff0c;我们已经学习了其网络结构&#xff0c;然而实际上YOLOV7项目的难点并不在于其网络模型而是在于其损失函数的设计&#xff0c;即如何才能训练出来合适的bbox。 神经网络模型都有训练和测试&#xff08;推理&#xff09;过程&#xff0c;在Y…

QT JS交互、调用JS、传值

本文详细的介绍了QT JS交互、调用JS、传值的各种操作&#xff0c;包括QT向JS传递String字符串、包括QT向JS传递Int数字、包括QT向JS传递List数组&#xff0c;同时也接收JS向QT返回的List数组、JS向QT返回的Json、JS向QT返回的数字、JS向QT返回的字符串。 本文作者原创&#xff…

Vue基础8之Vue组件化编程、非单文件组件与单文件组件

Vue基础8Vue组件化编程对组件的理解一些概念的理解非单文件组件基本使用几个注意点组件的嵌套VueComponent一个重要的内置关系先导篇&#xff1a;原型对象正文&#xff08;可以理解为类的继承&#xff09;单文件组件Vue组件化编程 对组件的理解 传统方式&#xff1a; 使用组…

计算机网络-交换方式

目录电路交换&#xff08;Circuit Switching&#xff09;分组交换&#xff08;Packet Switching&#xff09;报文交换&#xff08;Message Switching&#xff09;电路交换、报文交换、分组交换的对比电路交换&#xff08;Circuit Switching&#xff09; 在电话问世后不久&#…

扫雷游戏的设计(百分百还原电脑操作)

目录 &#x1f332;了解扫雷游戏的作用原理并梳理思路 &#x1f332;扫雷游戏前期部分完善 &#x1f337;文件的创建 &#x1f337;创建菜单&#xff0c;完善主函数 &#x1f333;代码呈现&#xff1a; &#x1f332;扫雷游戏主题内容 &#x1f334;第一步初始化棋盘 &#x1…

Gradle中如何修改Springboot引入的依赖版本

扫描漏洞升级 不知道各位是否遇到过以下问题&#xff1a; 当下层项目将spring引入的某个依赖版本升级之后&#xff0c;上层项目只要指定了Springboot版本&#xff0c;那么还是会将这个版本改回去&#xff1f; 比如&#xff1a;现在有两个Springboot项目A、B&#xff0c;B项目…

Git安装和配置

GitGitee 官网安装配置教程&#xff1a;https://gitee.com/help/articles/4104本文是以官网教程为基础而展开的实践笔记。初学者可以以本文为引入&#xff0c;但建议最终以官方文档为最终深入学习的参考。一、 下载和安装Git 1、官网下载&#xff1a;https://git-scm.com 如果对…

HTML5基础

HTML5 文章目录HTML5概述开发工具浏览器开发软件DemoHTML5语法HTML5标签HTML5标签属性HTML5文档注释HTML5文档结构头部内容主体内容DemoHTML5常见标签常见块级标签标题标签水平线标签段落标签换行标签引用标签预格式标签无序列表标签有序列表标签定义列表标签分区标签常见行级标…

【Java寒假打卡】Java基础-继承

【Java寒假打卡】Java基础-继承一、继承的好处和弊端二、继承的成员变量访问特点三、重写方法四、方法重写的注意事项五、权限修饰符六、构造方法一、继承的好处和弊端 继承的好处 提高了代码的复用性 提高了代码的维护性 让类和类之间产生了关系 是多态的前提 继承的弊端 …

Flink-使用filter和SideOutPut进行分流操作

文章目录1.什么是分流&#xff1f;2. 过滤器(filter)3. 使用侧输出流&#xff08;SideOutput&#xff09;&#x1f48e;&#x1f48e;&#x1f48e;&#x1f48e;&#x1f48e; 更多资源链接&#xff0c;欢迎访问作者gitee仓库&#xff1a;https://gitee.com/fanggaolei/learni…

四、网络层(七)网络层设备

目录 7.1 路由器的组成和功能 7.2 路由表与路由转发 7.1 路由器的组成和功能 路由器是一种具有多个输入/输出端口的专用计算机&#xff0c;其任务是连接不同的网络&#xff08;可以是异构的&#xff09;并完成路由转发。在多个逻辑网络&#xff08;即多个广播域&#xff…

Vulnhub靶机:HACKADEMIC_ RTB1

目录介绍信息收集主机发现主机信息探测网站探测Sql注入挂马提权介绍 系列&#xff1a;Hackademic&#xff08;此系列共2台&#xff09; 发布日期&#xff1a;2011年9月6日 难度&#xff1a;初级 运行环境&#xff1a;VMware Workstation 目标&#xff1a;取得 root 权限 flag…

5W2H分析法

什么是5W2H 5W2H分析法又叫七何分析法&#xff0c;是二战中美国陆军兵器修理部首创。简单、方便&#xff0c;易于理解、使用&#xff0c;富有启发意义&#xff0c;广泛用于企业管理和技术活动&#xff0c;对于决策和执行性的活动措施也非常有帮助&#xff0c;也有助于弥补考虑…

【UE4 第一人称射击游戏】07-添加“AK47”武器

素材资料地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1epyD62jpOZg-o4NjWEjiyg 密码&#xff1a;jlhr 效果&#xff1a; 步骤&#xff1a; 1.打开“WalkRun_BS”&#xff0c;将内插时间改为1 2.创建一个文件夹&#xff0c;命名为“Weapons” 进入“Weapons”…

可视化数据图表-FineReportJS实现清空控件内容

1. 概述 1.1 问题描述 在使用查询控件时&#xff0c;有时我们希望能够快捷重置控件的内容&#xff0c;或者重置所有控件的内容。效果如下图所示&#xff1a; 重置某个控件的内容&#xff1a;1.2 实现思路 在使用查询控件时&#xff0c;有时我们希望能够快捷重置控件的内容&a…