美文网首页
java并发concurrency

java并发concurrency

作者: 陈菲TW | 来源:发表于2020-02-26 18:30 被阅读0次

理解并发从例子开始:作为用电脑的小白使用者,并发就是一边记笔记一边听音乐,通过cpu在各个进程间切换实现并发;作为常规程序员,web服务中每个请求对应一个线程,服务端可同时处理多个请求,这也是并发;作为高效程序员,通过并发的方式调用第三方系统从而提高效率;作为一个用户友好程序员,长时间执行的任务可以用一个线程执行,从而不影响用户交互;再比如网红‘事件驱动开发’,每个事件的处理也是并发的。

Java中通过线程实现并发,并采用抢占式资源调度,因此可能出现类似下面的情形:‘平行时空,多个人在多个平行时空吃一桌饭,彼此看不到彼此的存在,我想吃鸡腿,突然就不见了,原来我被suspend,来自另一个平行时空的我吃掉了鸡腿。’,这就是共享变量引发的线程安全问题。更多关于线程安全的问题详见我的文章:https://www.jianshu.com/p/cd41921e5f8e

并发concurrent vs 并行parallel:并发包括单核CPU下时分切换,和多核CPU下同时执行(并行)。其中单CPU下的假并行不能提高效率,相反上下文切换会降低效率。

ConcurrentHashMap也关联到这里:https://www.jianshu.com/p/516a809ce41a

Java对并发的支持:concurrent包

1. Thread类

1)生命周期相关:Thread.start()用于启动线程;Thread.yield()任务提前完成则通过该方法通知调度器出让执行资源。

2)线程属性包括:名称/group/优先级/类型/状态。名称:例如main线程就是main函数执行线程;group默认为pool-1-thread-1;类型:通过Thread.setDaemon(true)设置线程为守护线程,守护线程后台运行,创建的线程都结束后才会结束,守护线程创建的线程都是守护线程;优先级和状态在上面另外两篇文章涉及。

3)Thread.currentThread():在task中调用来查看执行该task的线程。

2. 异常

线程抛出的异常不会传递回主线程,因此task中必须处理异常。

InterruptedException:比如sleep方法声明了InterruptedException。当处于阻塞状态的线程被interrupt时,或者被interrupt的线程试图进入阻塞状态时会抛出这个异常。

可以通过UncaughtExceptionHandler来处理并发异常

3. 可执行任务Task

1)Callable接口提供call()方法;Future接口提供isDone方法来判断是否执行完成;执行完成后调用Future的get方法获取结果。

2)Runnable接口提供run()方法。

4. 通过Executors+ExecutorService来管理线程

Executors相当于工厂,用于创造ExecutorServcie:ExecutorService service = Executors.newCachedThreadPool();

ExecutorService提供接口执行任务:service.execute(new RunnableTask()); Future<T> result = service.submit(new CallableTask()); service.invokeAll/invokeAny用于批量执行;service.shutdown(); shutdown表示停止接收task。

Executors用来创建线程池,弊端在于允许的最大值为Integer.MAX_INTEGER。CachedThreadPool;创建缓存线程池,调用该线程池的execute方法可重用以前的线程;FixedThreadPool固定大小线程池;SingleThreadExecutor串行执行。更加推荐使用ThreadPoolExecutor的构造函数来创建线程池。

相关文章

网友评论

      本文标题:java并发concurrency

      本文链接:https://www.haomeiwen.com/subject/hhcbchtx.html