并发编程知识点汇总(1)

1. 在 Java 中 Lock 接口 比 synchronized 块的优势是什么?

Lock 接口在多线程和并发编程中最大的优势是它们为读和写分别提供了锁, 它能满足你写想 ConcurrentHashMap 这样的高性能数据结构和有条件的阻塞. 

2. 在 Java 中 wait 和 sleep 方法的不同

wait等待时会释放锁, 而sleep等待时会一直持有锁.

wait是用来解决线程间的顺序问题, sleep则是用来让线程休眠一会儿

3. 用 java 实现阻塞队列

//基于数组来实现队列
class MyBlockingQueue{
    private int[] items = new int[1000];
    //约定[head,tail)队列,前闭后开
    volatile private int head = 0;
    volatile private int tail = 0;
    volatile private int size = 0;

    //入队列
    synchronized public void put(int elem) throws InterruptedException {
        while(size == items.length){
            // 队列满了,插入失败
            //return;
            this.wait();
        }
        //把新元素方放到 tail位置上
        items[tail] = elem;
        tail++;
        //万一tail达到末尾, 需要tail从头再来
        tail = tail % items.length;
        size++;
        this.notify();
    }
    //出队列
    synchronized public Integer take() throws InterruptedException {
        while(size == 0){
            this.wait();
        }
        int value = items[head];
        head++;
        if(head == items.length){
            head = 0;
        }
        size--;
        this.notify();
        return value;
    }

}

4. 用 java 写代码解决生产者--消费者问题

这里用到了上述的阻塞队列

public class ThreadDemo12 {
    public static void main(String[] args) {
        MyBlockingQueue queue = new MyBlockingQueue();
        //消费者
        Thread t1 = new Thread(() -> {
            while (true){
                try {
                    int value = queue.take();
                    System.out.println("消费" + value);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        t1.start();

        //生产者
        Thread t2 = new Thread(() -> {
            int value = 0;
            while(true){
                try {
                    queue.put(value);
                    System.out.println("生产" + value);
                    value++;
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }

        });
        t2.start();

    }
}

4. 死锁的四个必要条件

  • 互斥使用. 一个线程拿到一把锁之后, 另一个线程不能使用
  • 不可抢占: 一个线程拿到锁, 只能自己主动释放, 不能被其他线程强行占有
  • 请求和保持: 在拿到1号锁后, 想同时持有2号锁, 并且不会将1号锁释放
  • 循环等待: 一个线程在拿一个被占用的锁时, 会一直循环等待到该锁释放

前面两个为锁的基本特点, 后两个为代码的特点

5. 如何防范死锁

  • 尽量避免使用多个锁
  • 规范使用多个锁, 设计好锁的获取顺序
  • 随用随放. 手里有锁, 如果还要获取别的锁, 必须释放全部资源才能各取所需
  • 规范好循环等待条件. 比如使用超时循环等待, 提高程序可控性

6. Java 中的 volatile 关键是什么作用?

作用:

  • 保证内存可见性
  • 不让指令重排序
  • 不保证原子性

怎么使用:

在某个属性被多个线程共享, 其中一个线程修改了此属性, 其他线程可以立即得到修改后的值. 因此如果是对一个共享变量进行多个线程的赋值, 而没有其他的操作, 那么可以用 volatile 来代替

7.在 Java 中 volatile 跟 synchronized 方法有什么不同

  • volatile 只能修饰实例变量和类变量, 而 synchronized 可以修饰方法, 代码块
  • volatile 保证数据的可见性, 但是不保证原子性, 无法保证线程安全, 而 synchronized 是一种互斥机制, 能保证线程安全

8. 怎么使用 volatile

某个属性被多个线程共享, 其中有一个线程修改了此属性, 其他线程可以立马得到修改后的值. 因此如果是对一个共享变量进行多个线程赋值, 而没有其他操作, 那么就可以用 volatile 来代替

9. 什么是竞争条件? 你怎么发现和解决竞争

竞争条件发生在多个线程同时访问同一个共享代码, 变量, 文件等没有进行锁操作或者同步操作的场景中

怎么发现:

使用 burpsuite 和 Inturder 模版, 将线程调到25进行多线程异步发包, 也可以使用 curl 同时发包. 通过查看多个异步请求返回的不同结果, 比如11个测试中只有10个相同, 那一个包肯就是攻击成功的请求.

解决竞争:

对共享数据要进行上锁操作

10. 为什么我们调用 start() 方法时会执行 run() 方法, 为什么我们不能直接调用 run() 方法

调用 start 时会创建新的线程, 并且执行在 run() 方法里的代码. 如果直接调用 run() 方法, 它不会创建新的线程, 也不会执行调用线程的代码

11. Java 中你怎么样唤醒一个阻塞的线程

如果线程遇到了 IO 阻塞, 我不认为有一种方法可以中断线程. 如果线程因为调用 wait(), sleep(), join() 方法而导致的阻塞, 可以中断线程, 并且通过抛出 InterruptedException 来唤醒它.

12. 什么是不可变对象, 它对写并发应用有什么帮助

不可变对象是对象一旦被创建它的状态就不能改变, 反之即为可变对象

不可变对象的类即为不可变类, Java平台类库中包含许多不可变类, 如 String, 基本类型的包装类, BigInteger 和 BigDecimal等.

不可变对象天生是线程安全的, 所以在使用时不需要进行加锁等消耗资源的操作.

接下来的问题可能就是 String 为什么是不可变对象.

13. 你在多线程环境中遇到的常见问题是什么? 你怎么解决它的

多线程和并发程序中常遇到的有 Memory-interface、竞争条件、死锁、活锁和饥饿

基于面试进行回答

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值