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

本文介绍了三个多线程编程的实例:一是两个线程进行猜数字游戏,线程A随机数,线程B猜数并调整范围;二是键盘输入练习,线程A给出字符,线程B输入并判断得分;三是三个线程轮流打印ABC,通过锁实现同步;四是多窗口卖票模拟,三个线程共享资源卖票,展示了并发控制在实际问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

猜数字游戏

题目说明:有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();

    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

珍妮玛•黛金

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

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

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

打赏作者

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

抵扣说明:

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

余额充值