面试中经常手撕的多线程代码

看了好多的面经,手撕代码中除了算法题最常出现多线程的问题了,以下几个问题是总结了下出现比较多的,做一下记录,方便多看看

多线程下卖票

synchronized实现
只要有票就可以卖,卖之前第二次检查,保证多线程下不会卖出负数

class SellTacket implements Runnable {
   

    static int count = 100;
    static Object lock = new Object();

    public static void main(String[] args) {
   
        SellTacket sellTacket = new SellTacket();
        for (int i = 0; i < 20; i++) {
   
            new Thread(sellTacket, "卖票员" + i).start();
        }
    }


    @Override
    public void run() {
   
        while (count > 0) {
   
            synchronized (lock) {
   
                if (count > 0) {
   
                    count--;
                    System.out.println(Thread.currentThread().getName() + "卖出一张票,库存为:" + count);
                    try {
   
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

两个线程交替打印0-100奇偶数

两个线程启动之间睡眠1秒,保证偶数线程先启动
当打印完成一次后唤醒另一个线程,如果还有打印任务就wait当前线程等待被唤醒

class MyPrint implements Runnable {
   

    private static int count = 0;
    private static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
   
        new Thread(new MyPrint(), "偶数").start();
        Thread.sleep(1000);
        new Thread(new MyPrint(), "奇数").start();
    }

    @Override
    public void run() {
   
        while (count <= 100) {
   
            synchronized (lock) {
   
                System.out.println(Thread.currentThread().getName() + ":" + count++);
                lock.notifyAll();
                if (count <= 100) {
   
                    try {
   
                        lock.wait();
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

三个线程交替打印0-100的数

三个线程就不能简单的执行文唤醒直接执行了
使用ReentrantLock+自旋+双重检查操作,如果线程执行到打印位置不该他打印,就自旋等待合适了再操作

class MyPrint {
   
    private static Lock lock = new ReentrantLock();//定义一个lock锁
    private static int count = 0;//确定打印的是什么内容

    public static void main(String[] args) {
   
        new ThreadA().start();
        new ThreadB().start();
        new ThreadC().start();
    }

    static class ThreadA extends Thread {
   
        @Override
        public void run() {
   
            while (count <= 100) {
   
                try {
   
                    lock.lock();
                    while (count % 3 == 0 && count <= 100) {
   //自旋
                        System.out.println(Thread.currentThread().getName() + ":" + count++);
                    }
                } finally {
   
                    lock.unlock();
                }
            }
        }
    }

    static class ThreadB extends Thread {
   
        @Override
        public void run() {
   
            while (count <= 100) {
   
                try {
   
                    lock.lock();
                    while (count % 3 == 1 && count <= 100) {
   //自旋
                        System.out.println(Thread.currentThread().getName() + ":" + count++);
                    }
                } finally {
   
                    lock.unlock()
  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值