面试题总结 - 多线程 并发

三. 多线程 并发

3.1 线程间通信的方式有哪些

  1. 传统的线程通信
    使用synchronized 修饰的同步方法或者同步代码块,使用Object类下的wait() notify() notifyAll() 方法控制线程通信
    wait() 导致该线程阻塞等待其他线程使用notify() 方法唤醒
    notify()唤醒在此同步监视器的某一个线程
    notifyAll() 唤醒此同步监视器的全部的线程

  2. 使用Condition
    使用Lock 当作同步的对象,由于没有隐式的监视器,使用Condition类的await() signal() signalAll()方法实现通信

  3. 使用组赛队列
    BlockingQueue 实现消费者生产者
    put() 尝试往队列里面放入元素,满了就会阻塞
    take() 尝试拿出元素 空就阻塞

BlockingQueue实现生产者 消费者

public class BlockingQueueTest3 {

    class Producer extends Thread{

        public BlockingQueue<String> bq;
        public Producer(BlockingQueue<String> queue){
            this.bq = queue;
        }

        @Override
        public void run(){
            String product_name = Thread.currentThread().getName();
            System.out.println("我已经生产了"+Thread.currentThread().getName());
            try {
                bq.put(product_name);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class Consumer extends Thread{
        BlockingQueue<String> bq;

        public Consumer(BlockingQueue<String> bq){
            this.bq = bq;
        }
        @Override
        public void run(){
            try {
                String product_name = bq.take();
                System.out.println("消费了:"+product_name);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        BlockingQueue<String> bq = new LinkedBlockingDeque<>(1);
        BlockingQueueTest3 bb = new BlockingQueueTest3();
        for (int i = 0; i < 5; i++) {
            bb.new Producer(bq).start();
            bb.new Consumer(bq).start();
        }
    }
}

3.2 HashMap,ConcurrentHashMap

3.3 synchronized加到普通方法和静态方法的区别

static 获得的是类的锁,非静态获得到的是实例的锁

不会产生互斥

3.4 一个类的两个方法都加了synchronized,是一个锁还是两个锁;

一个,同一个对象锁只能被一个线程占用

未完待续

发布了118 篇原创文章 · 获赞 5 · 访问量 8729

猜你喜欢

转载自blog.csdn.net/weixin_43672855/article/details/105466953