Java多线程/并发
文章平均质量分 58
快速上手运用java多线程开发
唐大麦
只要往前走,就不会迟。精疲力尽的时侯应该选择休息,切不可放弃。
展开
-
Java多线程/并发01、新建线程的3种方法
引子首先要理解并发(Concurrency)和并行(Parallelism)的区别:并发是在同一时段发生。多线程就是分时利用CPU,宏观上让所有线程一起执行,也叫并发。但在微观上不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。这就好像两个人用同一把铁锨,轮流挖坑,一小时后,两个人各挖一个小一点的坑,要想挖两个大一点得坑,一定会用两个小时。并行是在同一时刻发生。无论从微观还是宏观,原创 2017-04-28 15:46:35 · 2068 阅读 · 1 评论 -
Java多线程/并发02、线程的五种状态
本篇摘录了网上相关文档和图片。 VM启动时会有一个由主方法Main所定义的主线程,在主线程中可以通过Thread创建其它线程。 Thread对象的方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。 通俗的说就是在run()方法中定义要做什么事情,start()方法用来发出命令可以开始做了,但这不代表JVM会立即运行 run()方法中的内容,而只是让他具备运行的原创 2017-04-28 15:50:06 · 2957 阅读 · 0 评论 -
Java多线程/并发03、实现定时任务的3种方法
所谓定时任务有两个核心要素: 1、任务开始时间:可以指定任务在将来某个时间点运行,或者指定任务从现在开始延迟一个时间段运行 2、任务执行周期:可以指定该任务每间隔多久执行一次Java实现定时任务有三种方法:一、利用Thread及Sleep实现,通过while循环让其不停运行public class TimerTaskDemo { public static void main(Strin原创 2017-04-28 15:52:44 · 10181 阅读 · 0 评论 -
Java多线程/并发04、synchronized同步
一、synchronized使用多个线程并发时,经常面临的问题就是会操作相同的资源。比如商品下单,库存量修改,转帐等。 举个例子: 家里有一口炒菜的锅,老大要做辣椒炒肉(制作步骤:a1.放肉,a2.放盐,a3.放辣椒),老二要做番茄炒蛋(制作步骤,b1.放蛋,b2.放盐,b3.放番茄)。两人把食材准备好后,都要抢着炒自己拿手的菜。老大往锅里放肉(a1),老二这时挤过来,放蛋(b1),放盐(b2)原创 2017-04-28 15:59:08 · 921 阅读 · 3 评论 -
Java多线程/并发05、synchronized应用实例:线程间操作共享数据
电商平台中最重要的一点就是卖东西。同个商品不能无限制的卖下去的,因为商品有库存量,超过库存就不能卖了。 这里,约定一个规则,下单使库存减n,取消订单使库存加m。库存数量不可以小于0。 假设平台上同时有很多用户在操作,在不考虑效率的情况下,我们用同步方法来模拟这个场景。首先写一个订单处理类:class OrderHandler{ /*初始某商品库存量*/ int StockSome原创 2017-04-28 16:03:55 · 2185 阅读 · 0 评论 -
Java多线程/并发06、线程锁Lock与ReadWriteLock
java的基本锁类型,都以接口形式出现,常用的有以下两种锁的接口:Lock锁。它的实现有ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLockReadWriteLock锁。它的实现有ReentrantReadWriteLock。一、lock简单使用方法1、Lock锁基本都是排他锁,它和s原创 2017-04-28 16:07:30 · 1007 阅读 · 1 评论 -
Java多线程/并发07、Thread.Join()让调用线程等待子线程
开始之前,有几点要理解的: 1、当程序运行的时侯,系统默认开启了一个主线程(假设命名mainThread)。通常我们在Main()函数中定义主线程的工作。 2、可以在Main()函数中启动多个子线程:Thread-1,Thread-2,Thread-3等。 3、主线程有可能比子线程先结束运行。第三点是关键,这也是要用到join()方法的一个重要原因,因为有时侯我们希望主线程等待子线程执行完成之原创 2017-04-28 16:31:24 · 1892 阅读 · 0 评论 -
Java多线程/并发08、中断线程 interrupt()
一个线程是否能让另一个线程停止运行?除了线程同步互斥机制之外,还有两种方法:可以使用Thread.stop(), Thread.suspend(), Thread.resume() 和Runtime.runFinalizersOnExit() 这些终止线程运行的方法 。但这些方法已经被废弃(The method stop() from the type Thread is deprecated)原创 2017-04-28 16:34:45 · 851 阅读 · 0 评论 -
Java多线程/并发09、浅谈volatile
在了解volatile之前,先介绍一个名词:liveness failure ,直译叫作活性失败。因为这是volatile很重要的一个应用场景:public class volatileDemo { private static boolean stopFlag; public static void main(String[] args) throws InterruptedExc原创 2017-04-28 16:37:34 · 2357 阅读 · 3 评论 -
Java多线程/并发10、不可重入锁/自旋锁、可重入锁
锁分为可重入锁和不可重入锁。 可重入和不可重入的概念是这样的:当一个线程获得了当前实例的锁,并进入方法A,这个线程在没有释放这把锁的时候,能否再次进入方法A呢?可重入锁:可以再次进入方法A,就是说在释放锁前此线程可以再次进入方法A(方法A递归)。不可重入锁(自旋锁):不可以再次进入方法A,也就是说获得锁进入方法A是此线程在释放锁钱唯一的一次进入方法A。先举例来说明锁的可重入性:public原创 2017-04-28 16:39:55 · 7634 阅读 · 3 评论 -
Java多线程/并发11、线程同步通信:notify、wait
假设有两个线程,一个线程负责打印5次”Hello”,一个线程负责打印5次”Word”。现在提出一个要求,要求两个线程交替打印,也就是要求Hello和Word交替出现。 我们先实现两个线程打印字符的功能。代码如下:package JConcurrence.Study;public class ExecuteDemo { public static void main(String[] ar原创 2017-04-28 16:42:13 · 1154 阅读 · 0 评论 -
Java多线程/并发12、多线程访问static变量
类的成员分为两类,静态成员(static member)和实例成员(instance member)。静态成员属于类;实例成员则属于对象,即类的实例。 先看一个类:public class staticDemo { static int result; static int Addone(Integer num){ Integer inner_result=num+原创 2017-04-28 16:46:05 · 13665 阅读 · 1 评论 -
Java多线程/并发13、保持线程间的数据独立: Collections.synchronizedMap应用
现在流行分布式计算,分布式计算就是先分开计算,然后统一汇总。比如这道题目: 。先别跑,小学题很简单的。 解释一下,左边那一砣是计算从1加到n的值(求和),右边是n乘到1的值(阶乘),再把两个值相加得到最终结果。假设求和运算需要5秒钟,阶乘运算需要7秒钟,相加的运算需要1秒,那么总耗时是13秒。而在分布式计算中,由两台机器同时进行计算,得到求和及阶乘的两个结果只需要7秒,再相加需要1秒,总耗时8秒原创 2017-04-28 16:50:17 · 1037 阅读 · 0 评论 -
Java多线程/并发14、保持线程间的数据独立:ConcurrentHashMap应用
在Java 1.5之前,如果需要可以在多线程和并发的程序中安全使用的Map,只能在HashTable和Collections.synchronizedMap中选择,因为它们的put、reomve和containsKey方法都是同步的。我们熟知的HashMap不是线程安全的,因此在多线程环境下开发不能用这个。HashTable容器使用synchronized来保证线程安全,因此读和写都是串行的,在线程原创 2017-04-28 16:53:54 · 1418 阅读 · 0 评论 -
Java多线程/并发15、保持线程间的数据独立:ThreadLocal应用
文档上(http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html)这么写的 This class provides thread-local variables. These variables differ from their normal counterparts in that each thread t原创 2017-04-28 17:03:20 · 2513 阅读 · 0 评论 -
Java多线程/并发16、Atomic原子变量和原子操作
在Java中,i++这类的操作看起来只有一行,其实java 分成了三步去做 1、获取i值 2、计算i+1; 3、将结果存入i; 因此i++不是原子操作,非线程安全的,多线程访问的时候需要用到synchronized关键字保持线程同步。synchronized是悲观锁,在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,代价就是效率低下。 更加高效的锁就是乐观锁,所谓乐观锁就是不原创 2017-04-28 17:11:05 · 4610 阅读 · 0 评论 -
Java多线程/并发17、简述CAS 操作
摘录网上一些文章什么是CASCAS,Compare and Swap即比较并交换。 java.util.concurrent包借助CAS实现了区别于synchronized同步锁的一种乐观锁。乐观锁就是每次去取数据的时候都乐观的认为数据不会被修改,所以不会上锁,但是在更新的时候会判断一下在此期间数据有没有更新。 CAS有3个操作数:内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存原创 2017-04-28 17:14:30 · 874 阅读 · 0 评论 -
Java多线程/并发18、Java线程池
用过数据库的,都了解连接池概念。为了减少建立连接的开销,预先建立好多条连接,由连接池对象统一管理。当有进程需要连接数据库时,就分配一条空闲的连接给它,用完再被收回等待分配给下一个进程使用。 线程池的概念也一样,根据设置预先创建好一些线程,需要时就分配给你,使用完再收回,这样就不用老是去new Thread()了。Java通过Executors提供四种线程池,分别为: 1、newCachedThr原创 2017-04-28 17:17:14 · 1009 阅读 · 0 评论 -
Java多线程/并发19、Callable、Future接口及CompletionService的应用
我们知道Runable()是无法直接返回值的。如果某个线程想获取另一个线程中变量的值,怎么办呢? Java为我们提供了一种处理模式——Future模式: 线程A(生产者)处理一个很耗时的工作,将会生产出一个结果。线程B(消费者)可以随时拿线程A的结果进行下一步处理。同时线程B(消费者)可以获取线程A的任务运行状态,也可以取消线程A的任务运行。 打个比喻:你到千吉买月饼,千吉收钱后给你开了一张月原创 2017-05-04 20:47:07 · 1036 阅读 · 0 评论 -
Java多线程/并发20、Future实现类:FutureTask
FutureTask是future的实现类,它同时实现了两个接口:Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。因此我们可以: - 调用FutureTask对象的run()方法执行 - 调用FutureTask对象的get()方法取结果 - 也可以将FutureTask对象作为callable的实现用线程池原创 2017-05-04 20:52:32 · 3887 阅读 · 0 评论 -
Java多线程/并发21、利用Condition来实现阻塞队列
Java文档上的例子,利用Condition来实现阻塞队列。 假设有一个固定大小的缓冲区(缓冲区是队列,遵守FIFO),支持存和取方法。如果缓冲区为空时尝试取数据,那么线程将阻塞,直到缓冲区有一个可用的数据;如果缓冲区满了,这时尝试写数据,那么线程将被阻塞直到有可用空间。我们希望有两个独立的等待集(Condition阻塞队列),一个放置存数据的等待线程,一个放置取数据的等待线程,这样,当缓冲区有空原创 2017-05-04 20:56:33 · 1406 阅读 · 1 评论 -
Java多线程/并发22、信号量Semaphore
Semaphore通常用于设置一些资源(如数据库连接池,程序某个变量)可供线程使用的数量,它有两个很常用的方法是acquire()和release()。打个通俗的比方:一个饭店有10间包房,客人消费前先到前台领一张包房券(调用一次acquire 包房券-1),进入包房用餐直到酒足饭饱后,再到前台退回包房券(包房券+1)并结帐(调用一次release())。而前台工作人员呢,手上一共10张包房券(对应原创 2017-05-04 21:00:14 · 1665 阅读 · 0 评论 -
Java多线程/并发23、循环屏障CyclicBarrier
CyclicBarrier 直译叫循环屏障或循环分界点。让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续工作。打个比方,F1大奖赛共5支车队参赛。第一站:上海站。比赛马上要开始了,各个车队都在准备,但是先到达起跑线准备就绪的车队没法开始比赛,必须等待。只有当5支车队都到达起跑线准备就绪后,裁判才可以发起比赛。这5个车队到达起跑线原创 2017-05-04 21:03:28 · 1608 阅读 · 0 评论 -
Java多线程/并发24、Countdownlatch应用以及与CyclicBarrier的区别
有时候会有这样的需求:多个线程同时工作,其中几个可以随意的并发执行,但有一个线程需要等其他线程工作结束后,才能运行。举个例子,我们知道的迅雷下载,会同时开启多个线程分块下载一个大文件,每个线程下载固定的一段,最后由另外一个线程校验并拼接这些分段。这种场景可使用CountDownLatch来控制并发的执行顺序。Countdownlatch 是一个倒计数器锁。调用CountDownLatch对象的awa原创 2017-05-07 15:17:15 · 1315 阅读 · 0 评论 -
Java多线程/并发25、Exchanger线程数据交换
Exchanger用于线程间的数据交换。它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。 这句话说到两个关键点:Exchanger只能用于两个线程互相交换数据。如果有三个线程呢?对不起,臣妾做不到……Exchanger会产生一个同步点。一个线程先执行到达同步点,就会阻塞,等到另一个线程。两个都到达同步点后,开始交换数据。线程方法中调用exchanger.exchange()的地方就是原创 2017-05-07 15:19:49 · 1351 阅读 · 0 评论 -
Java多线程/并发26、阻塞队列BlockingQueue
BlockingQueue接口定义了一种队列,这种队列通常容量是提前固定(确定了容量大小)的。容量满时往BlockingQueue中添加数据时会造成阻塞,容量为空时取元素操作会阻塞。我们可以认为BlockingQueue队列是一个水库。水库满了的时侯,上游的水就要被拦住,不能再往水库里灌了。平时农庄浇灌,生活饮用都用这里面的水。如果水库干了,那么要灌溉的工人只能等着上游放水后,才能继续工作。 实际原创 2017-05-07 15:25:58 · 2991 阅读 · 0 评论 -
Java多线程/并发27、DelayQueue延迟队列模拟实现Session
DelayQueue延迟队列理解: 1、DelayQueue队列中的元素必须是Delayed接口的实现类,该类内部实现了getDelay()和compareTo()方法,第一个方法是比较两个任务的延迟时间进行排序,第二个方法用来获取延迟时间。 2、DelayQueue队列没有大小限制,因此向队列插数据不会阻塞 3、DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元原创 2017-02-28 15:29:42 · 3398 阅读 · 0 评论