深入浅出谈java进阶——多线程

2021-01-12  本文已影响0人  辻老板

多线程

线程的 5 个状态的理解:

1. 新建,刚刚新建的线程,还未进入就绪队列

2. 就绪,进入就绪队列的线程拥有了获得 CPU 时间的机会,但不是一定会马上执行,与线程调度有关。

3. 运行,获得了 CPU 时间,正在被执行的线程。

4. 阻塞,进入阻塞状态的线程只是暂时失去了 CPU 时间,该类线程没有结束,“阻塞态”的线程只能进入到“就绪态”。

5. 死亡,死亡的线程即彻底结束了。

1.线程同步

CountDownLatch 一个或多个线程等待其他线程完成一系列操作后才执行

CyclicBarrier  多个线程互相等待,直到到达同一个同步点,再继续一起执行。适用于多个线程有固定的多步需要执行,线程间互相等待,当都执行完了,在一起执行下一步。

Phaser; 与cyclicbarrier类似,功能更强。它支持任务在多个点都进行同步,支持动态调整注册任务的数量

Exchanger 可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据,当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行

Semaphore: 可以控制同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可; 比如多个窗口叫号,窗口都忙时,顾客等待,有空闲时,最新等待的被通知

任务1:理解,通过看源码

任务2:通过练习demo,加深理解

任务3:区分各种使用场合

2.Java 8使用CompletableFuture编写异步任务

CompletableFuture类的一系列aync结尾的方法,可以启动一个异步任务,既可以在默认的线程池运行,也可以指定线程池。CompletableFuture类也包含了对CompletableFuture的各种组合(then开头的方法)、结果获取的方法。 例如,异步地通过网址获取链接集,然后再异步地下载链接集的文本内容

任务1:对比CompletableFuture和Future

任务2:练习demo

3.线程thread.interrupt()

4.Thread.sleep/Object.wait区别

sleep()方法

阻塞——sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;

不释放锁——sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。

不立刻执行——在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。

wait()方法

释放锁——wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问;

notify唤醒——wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。

synchronized 中——wait()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常。

5.Volatile和AtomicInteger,AtomicIntegerArray线程安全操作

新增一个AtomicIntegerArray的getAndAdd()方法的考察

(1)getAndAdd()方法返回索引所在未知的数值,并把该位置的值增加一个Delta数值回填到索引位置

(2)所以value的值是默认的2,而变更后的数值是2+5=7

01publicclass Test {02privatestaticint[] arr =newint[]{1, 2, 3};03privatestaticAtomicIntegerArray integerArray =new AtomicIntegerArray(arr);04    05publicstaticvoid main(String[] args) {06intvalue = integerArray.getAndAdd(1, 5);07            System.out.println(integerArray.get(1));08            System.out.println(value);09        }10    }

上一篇下一篇

猜你喜欢

热点阅读