架构学习——并发编程(一)

3 篇文章 0 订阅
2 篇文章 0 订阅

线程基础、线程之间的共享和协作

基础概念

  • 进程:程序运行时资源分配的最小单位;进程内部多线程共享进程的资源。
  • 线程:CPU调度的最小单位。
  • 并发:处理多个任务的能力,不一定同时。
  • 并行:同时处理多个任务的能力。
创建线程
  • 继承Thread
  • 实现Runnable
  • Callable
关闭线程
  • stop()
  • resume()
  • suspend()

上述三个方法关闭线程不推荐使用,因为线程不会释放资源,并可能造成死锁情况发生;因此推荐下述方法的使用。

  • interrupt() 中断线程,并非强制关闭,中断标志位置为true

  • isInterrupted() 判断当前线程是否中断

  • interrupted() 判断当前线程是否中断,中断标志位置为false

如果存在InterruptedException类型异常,标志位将被置为false

守护线程

守护线程中不要使用finally来关闭资源。因为守护线程为用户线程服务,不会退出JVM,任何代码(包括finally块)都不会在所有用户线程执行完成之后执行。

Volatile

原子操作:不可中断的一个或一系列操作。

volatile可以保证可见性,不一定保证原子性。

适用场景:只有一个线程写,其他线程读。

ThreadLocal

由于每个线程拥有一份数据副本,因此不会互相影响。而又因为每个线程均复制一份共享内存数据

因此不建议将大数据类型塞入ThreadLocal中。

等待和通知标准范式
  • 等待:

  • 获取对象的锁;

  • .循环里判断条件是否满足,不满足调用wait()方法;

  • 条件满足执行业务逻辑。

  • 通知:

  • 获取对象的锁;

  • 改变条件;

  • 通知所有等待该对象的线程。

join()

线程A调用线程B的join方法,线程A等待线程B执行完毕再执行自己的逻辑。

yield()

线程执行到yield()以后,持有的锁不会释放。

sleep()

线程执行到sleep()以后,持有的锁不会释放。

wait()

调用方法前,必须持有锁,调用wait()方法之后,锁会被释放;当wait()方法返回的时候,线程会重新持有锁。

notify()、notifyAll()

调动方法之前必须持有锁,调用notify()、notifyAll()方法本身不会释放锁。

fork/join(分而治之)

数据量为n的问题,n<阈值,直接解决;n>阈值,将n分解为k个子问题,子问题间互相对立,与原问题形式相同,最后将子问题的解合并到原问题的解返回。

同步实现:ForkJoinPool的invoke()方法

异步实现:ForkJoinPool的execute()方法

并发工具类

CountDownLatch

用途:一个线程等待其他的线程完成工作以后再执行,加强版join

await()使线程等待,countDown()计数器减一

适用场景:某些数据需要初始化之后,业务线程才能正常执行的业务场景。

CyclicBarrier

用途:让一组线程到达某一个屏障时被阻塞,一直到组内线程均到达屏障,屏障解除,所有被阻塞线程会继续运行。

await()使线程等待

适用场景:线程协作,只有不同线程任务完成,业务才可以向下执行。

CountDownLatch和CyclicBarrier区别

1.CountDownLatch放行条件由第三者控制,CyclicBarrier放行条件由一组线程本身控制

2.CountDownLatch放行条件>=线程数,CyclicBarrier放行条件=线程数

Semaphore

控制同时访问特定资源的线程数量,多用于流量控制

适用场景:连接池资源控制;高并发场景限流。

Exchange

两个线程间进行数据交换

Future、FutureTask、Callable
    Future接口定义方法
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    get() throws InterruptedException, ExecutionException;
    get(long timeout, TimeUnit unit)
boolean cancel(boolean mayInterruptIfRunning)

尝试取消任务的执行,取消成功返回true,取消失败返回false;mayInterruptIfRunning表示是否允许中断正在执行的任务。

  • 如果任务未开始,cancel返回true,并且任务永远不会被执行。
  • 如果任务正在执行,且mayInterruptIfRunning为true,会调用中断逻辑,返回true;如果为false,不会调用线程中断,只是取消任务。
  • 如果任务结束(正常完成、异常终止、被取消),返回false。
  • 如果cancel()操作返回true,再调用isDone()、isCanceled()都返回true。
boolean isCancelled()

表示任务是否被取消成功,如果在任务正常完成前被取消成功,返回true。

boolean isDone()

表示任务是否已经完成,完成则返回true,注意:正常、异常或取消均代表任务完成。

V get()和V get(long timeout,TimeUnite unit)
  • get()用来获取执行结果,这个方法会产生阻塞,直到任务执行完毕才返回。
  • get(long timeout,TimeUnite unit)同样是用来获取执行结果,如果指定时间内没有取到结果,会抛出TimeoutException。
    FutureTask部分代码
    /* Possible state transitions:
     * NEW -> COMPLETING -> NORMAL
     * NEW -> COMPLETING -> EXCEPTIONAL
     * NEW -> CANCELLED
     * NEW -> INTERRUPTING -> INTERRUPTED
     */

    private volatile int state;
    private static final int NEW          = 0;
    private static final int COMPLETING   = 1;
    private static final int NORMAL       = 2;
    private static final int EXCEPTIONAL  = 3;
    private static final int CANCELLED    = 4;
    private static final int INTERRUPTING = 5;
    private static final int INTERRUPTED  = 6;

    /** The underlying callable; nulled out after running */
    private Callable<V> callable;
    /** The result to return or exception to throw from get() */
    private Object outcome; // non-volatile, protected by state reads/writes
    /** The thread running the callable; CASed during run() */
    private volatile Thread runner;
    /** Treiber stack of waiting threads */
    private volatile WaitNode waiters;
state是任务的运行状态
  • 新建FutureTask,state处于NEW状态;COMPLETING和INTERRUPTING是两个中间状态,线程正常结束设置outcome属性前是COMPLETING,设置后变为NORMAL;当中断运行中线程的状态是INTERRUPTING,调用Thread.interuupt()后是INTERUUPTED;NORMAL代表顺利完成;EXCEPTIONAL代表过程出现异常;CANCELED代表执行过程被取消;INTERRUPTED被中断。
  • 执行过程顺利完成:NEW -> COMPLETING -> NORMAL
  • 执行过程出现异常:NEW -> COMPLETING -> EXCCEPTIONAL
  • 执行过程被取消:NEW -> CANCELED
  • 执行过程中,线程中断:NEW -> INTERRUPTING -> INTERRUPTED

callble是线程运行的有返回值的任务。

outcome是任务执行后的结果或异常。

waiters表示等待获取结果的阻塞线程,链表结构,后来线程会放在链表前面。

***更多资源关注公众号,不定时更新。***在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值