zoukankan      html  css  js  c++  java
  • 线程池中 work 为何要实现 AbstractQueuedSynchronizer

    Worker(Runnable firstTask) {
    setState(-1); // inhibit interrupts until runWorker
    this.firstTask = firstTask;
    this.thread = getThreadFactory().newThread(this);
    }

    protected boolean tryAcquire(int unused) {
    if (compareAndSetState(0, 1)) {
    setExclusiveOwnerThread(Thread.currentThread());
    return true;
    }
    return false;
    }

    protected boolean tryRelease(int unused) {
    setExclusiveOwnerThread(null);
    setState(0);
    return true;
    }

    public void lock() { acquire(1); }
    public boolean tryLock() { return tryAcquire(1); }
    public void unlock() { release(1); }
    public boolean isLocked() { return isHeldExclusively(); }

    Worker使用这个锁从队列中获取任务时加锁,每个线程同时只执行一个任务,不需要重入锁(如果是重入锁,就有可能同一个线程同时执行多个任务)
    其次 在Work运行时 

     w.lock的目的  如果task代码实现里有Thread.sleep或者join等,那就会被中断,task运行没完成,此时新的任务故还不能开始,所以用锁锁住

    注意 runWorker方法中 刚开始会进行解锁,是由于 解锁会将 state设置为0,代表此线程已经开始工作了,为什么要将state 设置为0 因为 新建Worker时将state设置为了-1

    顺便说一下 :

    void interruptIfStarted() {
    Thread t;
    if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
    try {
    t.interrupt();
    } catch (SecurityException ignore) {
    }
    }
    }
    线程池中线程中断 代表只会中断 worker是否已经开始运作(新建work时会将状态设置为 -1)
    如果有来生,要做一片树叶。 春天恋上枝,炎夏恋上水。 深秋恋上土,东来化作泥。 润物细无声,生生世世恋红尘。
  • 相关阅读:
    Golang使用os/exec时产生僵尸(defunct)进程
    golang channel 用法总结
    Git常用方法
    插入排序,冒泡排序,快速排序,选择排序,归并排序 C++代码实现
    Linux 系统安装golang
    Linux 压缩解压常用命令汇总
    云主机挂载硬盘
    Linux服务器如何修改内核版本号
    关于FreePBX语音网关对接遇到的伤心事
    Asterisk13.23.1如何增加G723编码和G729编码
  • 原文地址:https://www.cnblogs.com/shujiying/p/12436867.html
Copyright © 2011-2022 走看看