多线程面试题

两个线程一个打印奇数一个打印偶数

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

    @Test
    public void test() throws InterruptedException {
        Thread even = new Thread(new TurningRunner(), "偶数");
        even.start();
        // 确保偶数线程线先获取到锁
        Thread.sleep(1);
        Thread odd = new Thread(new TurningRunner(), "奇数");
        odd.start();
        even.join();
        odd.join();
    }

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

N个线程顺序循环打印从0至100

通过N个线程顺序循环打印从0至100,如给定N=3。则输出: thread0: 0 thread1: 1 thread2: 2 thread0: 3 thread1: 4

这道题很考察多线程基础。主要在于N个线程循环打印。关键在于如何控制线程的执行顺序,即唤醒特定的线程。之前通过notify()唤醒一个,notifyAll()唤醒全部,但都无法选择特定的线程执行。那如何控制控制线程有序的打印呢?

这里可以用semaphore信号量实现。设置semaphore[]数组,每个线程持有本身的信号量以及上个线程的信号量。对于三个线程abc来说,他们的last信号量对应关系为:

a.last - > semaphores[2]

b.last - > semaphores[0]

c.last - > semaphores[1]

每个线程执行时,会抢占last信号量,如a抢占 semaphores[2],同时释放当前信号量semaphores[0],通知等待队列中的线程b,这时线程b才能抢占通过它的last信号量:semaphores[0],同时再释放semaphores[1],然后唤醒c线程。。依此循环执行。

synchornized锁住的是什么

synchronized(obj) ,obj非static,锁的是实例对象,不是代码。当synchronized锁住一个对象后,别的线程如果也想拿到这个对象的锁,就必须等待这个线程执行完成释放锁,才能再次给对象加锁,这样才达到线程同步的目的。

synchronized(xx.class)锁的是class对象,全局性的,相当于锁住了代码块。

https://blog.csdn.net/xiao__gui/article/details/8188833

阻塞队列实现生产者消费者模型

手写生产者消费者模型

Last updated

Was this helpful?