前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA 并发真讨厌

JAVA 并发真讨厌

作者头像
疯狂的KK
发布2019-10-24 15:14:21
4090
发布2019-10-24 15:14:21
举报
文章被收录于专栏:Java项目实战

互联网行业随着商业化,信息化,快速发展至今,借助人口大国和时代催生,早已到了秀才不出门便知天下事的年代,80后吃饭就着菜,90后吃饭就着肉,00后吃饭就着paid,多媒体,小视频,流量明星,随着5G的普及,互联网将跨入新时代。

人口多,那么带给互联网就少不了高并发,什么叫高并发?单位时间内处理的请求量叫做高并发。高并发就离不开多线程操作。

既然是高并发,就对应了JUC包的API类。着重挑一些听得多的记录一下。

1.最常问:synchronized和Lock有什么区别?

①:synchronized是JVM层面实现的,java提供的关键字,Lock是API层面的锁。

②:synchronized不需要手动释放锁,底层会自动释放,

Lock则需要手动释放锁,否则有可能导致死锁

③:synchronized等待不可中断,除非抛出异常或者执行完成

Lock可以中断,通过interrupt()可中断

④: synchronized是非公平锁

Lock是默认公平锁,当传入false时是非公平锁

⑤:synchronized不可绑定多个条件

Lock可实现分组唤醒需要唤醒的锁

2. synchronized在修饰方法和修饰代码块的区别?

字节码结果不同

3.偏向锁对synchronized和ReentrantLock的价值?

UseBiaseLocking对synchronize有用

ReentrantLock已经实现了偏向锁UseBiaseLocking java5 6版本

4.当主线程退出时,守候子线程会执行完毕吗?

不一定执行 ti.setDaemon(true);

守候线程执行依赖于执行时间

5.请说明 ShutdownHook 线程的使用场景,以及如何触发执行?

优雅的停止线程

代码语言:javascript
复制
Runtime runtime=new Runtime();runtime.addShutDownHook(new Thread(()->{System.out.println("")),"");

6.最常见CAS和AQS的理解?

在Lock中常常听到CAS以及AQS的名词,根据个人理解整理下相关知识

CAS:compare and swap 比较并交换,判断取出内存中某时刻的数据并在当下时刻进行交换,缺点:循环时间长,只能保证一个共享变量的原子操作,引来ABA问题?

看下源码:

代码语言:javascript
复制
final boolean nonfairTryAcquire(int acquires) {            final Thread current = Thread.currentThread();            int c = getState();            if (c == 0) {                if (compareAndSetState(0, acquires)) {                    setExclusiveOwnerThread(current);                    return true;                }            }            else if (current == getExclusiveOwnerThread()) {                int nextc = c + acquires;                if (nextc < 0) // overflow                    throw new Error("Maximum lock count exceeded");                setState(nextc);                return true;            }            return false;        }

CAS核心是由native修饰的Unsafe类,其中valueOff为内存偏移量地址,变量由volatile修饰。

代码语言:javascript
复制
    /**     * Atomically increments by one the current value.     *     * @return the previous value     */  public final int getAndIncrement() {        return unsafe.getAndAddInt(this, valueOffset, 1);    }

AQS:AbstractQueuedSynchronizer,AQS是ReentrantLock的核心实现,将其比为一个框架

源码:

代码语言:javascript
复制
 final boolean nonfairTryAcquire(int acquires) {            final Thread current = Thread.currentThread();            int c = getState();            if (c == 0) {                if (compareAndSetState(0, acquires)) {                    setExclusiveOwnerThread(current);                    return true;                }            }            else if (current == getExclusiveOwnerThread()) {                int nextc = c + acquires;                if (nextc < 0) // overflow                    throw new Error("Maximum lock count exceeded");                setState(nextc);                return true;            }            return false;        }

看下本类

代码语言:javascript
复制
public abstract class AbstractQueuedSynchronizer    extends AbstractOwnableSynchronizer    implements java.io.Serializable {
    private static final long serialVersionUID = 7373984972572414691L;
    /**     * Creates a new {@code AbstractQueuedSynchronizer} instance     * with initial synchronization state of zero.     */    protected AbstractQueuedSynchronizer() { }...
}

提供方法很多

CAS如果看做是一个算法的话,AQS可以视为一个框架,

代码语言:javascript
复制
 /**     * Acquires in exclusive mode, ignoring interrupts.  Implemented     * by invoking at least once {@link #tryAcquire},     * returning on success.  Otherwise the thread is queued, possibly     * repeatedly blocking and unblocking, invoking {@link     * #tryAcquire} until success.  This method can be used     * to implement method {@link Lock#lock}.     *     * @param arg the acquire argument.  This value is conveyed to     *        {@link #tryAcquire} but is otherwise uninterpreted and     *        can represent anything you like.     */public final void acquire(int arg) {        if (!tryAcquire(arg) &&            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))            selfInterrupt();    }

传入arg参数,默认为0,以独占模式获取,忽略中断。通过至少调用一次实现

7:CountDownLatch 与 CyclicBarrier 和Semaphore的区别?

CountdownLatch等待所有线程计数器变为0执行一系列操作后唤醒,

CyclicBarrier 可循环屏障,所有被屏障拦截的的线程完毕才会干活,相当于i++,但这样理解是不正确的,因为CyclicBarrier的await()实际是做了--i操作。

代码语言:javascript
复制
private int dowait(boolean timed, long nanos)        throws InterruptedException, BrokenBarrierException,               TimeoutException {        final ReentrantLock lock = this.lock;        lock.lock();        try {            final Generation g = generation;
            if (g.broken)                throw new BrokenBarrierException();
            if (Thread.interrupted()) {                breakBarrier();                throw new InterruptedException();            }
            int index = --count;            if (index == 0) {  // tripped                boolean ranAction = false;                try {                    final Runnable command = barrierCommand;                    if (command != null)                        command.run();                    ranAction = true;                    nextGeneration();                    return 0;                } finally {                    if (!ranAction)                        breakBarrier();                }            }

Semaphore:信号量,控制并发线程数,指定线程执行。

未完待续...

声明:本文内容根据B站UP主mercyblitz,2019.4.07期视频以及历史资料整理,扫描二维码关注小马哥公众号,java劝退师,好东西需要分享,干货满满

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 赵KK日常技术记录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档