背景说明:
多线程并发与管理,是java基础知识里的重点,本文根据《java核心技术第八版》中的多线程技术的学习,对知识点进行整理;这里只对基础知识点进行简单罗列,以达到对知识点有网状关联的效果,能起到提纲挈领的作用,在于其它知识点融合时,有更好的一览效果。
线程概念
1.明确进程与线程的区别
2.不要调用Thread或Runnable对象的run方法,直接调用run方法,只会执行同一个线程中的任务,而不会启动新线程。应该调用Thread.start方法。这个方法将创建一个执行run方法地新线程。
中断线程
1.请求终止线程的方法是interrupt方法
2.在线程阻塞状态下调用interrupt方法时,会产生InterruptException异常。
3.有2个类似方法,interrupted和isInterrupted方法;interrupted是静态方法,它检测当前线程是否中断,并清除该线程的中断状态;isInterrupted是一个实例方法,可用来检验是否线程被终止,不改变线程的中断状态。
线程状态
- 新生
- Runnable 可运行状态
- Blocked 被阻塞
- Waiting 等待
- Timed waiting 计时等待
- Terminated 被终止
重点说明:
Thread的stop,suspend,resume方法已经过时。
Thread.join 方法等待终止指定的线程。注:如果有3个线程,依次分别执行,强调按照顺序执行,主要考察的就是这个方法地使用。
线程属性
属性包括:线程优先级,守护线程,线程组以及处理未捕获异常的处理器
1.优先级
可以设置最小到最大:1到10,norm_priority被定义为5
2.守护线程
作用就是为其它线程服务
同步
常用来举例就是多个线程同时存取钱或者是买火车票。
1.锁对象
从java1.5起,有2种机制可以防止代码受到并发访问的干扰:synchronized ,ReentrantLock.。把解锁操作括在finally子句之内是至关重要的。
2.条件对象
条件对象用来管理哪些已经获得了一个锁但是缺不能有用工作的线程。举例子:如果在多线程转账时,如果账户余额不足,需要等待其他线程转入金额时,就是典型用到条件对象的地方;这里面用到了锁,一个锁可以有一个或多个相关的条件对象。通过条件对象的await方法,当前线程就被阻塞了,并放弃了锁。一个线程调用了await方法,它进入了该条件的等待集,等锁可用时,该线程不能马上解除阻塞,相反它是处于阻塞状态,直到另一个线程调用同一个条件对象的signalAll方法时为止。
3.synchronized关键字
相当于一个内部锁,只有一个条件对象。利用Object的wait,notifyAll,notify;与条件对象里的方法不同:await,signalAll,singal
4.同步阻塞
5.Volatile域
对于域的并发访问是安全的:
- 域是final,并且在构造器调用完成之后被访问;
- 对域的访问,由共有锁进行保护
- 域是Volatile
6.锁测试与超时
因为lock方法是不能被中断的,如果一个线程在等待一个锁时被中断,中断线程在获得锁之前一直处于阻塞状态。如果出现死锁,那么lock方法就无法终止。然而调用带有超时参数的tryLock,那么线程在等待期间被中断,将抛出InterruptedException异常。这是一个非常有用的特性,因为允许程序打破死锁。
7.读写锁
如果很多线程从一个数据结构读取数据而很少线程修改其中数据的话,用ReentrantReadWriteLock类就非常有用。
阻塞队列
对于许多线程问题,可以通过使用一个或多个队列以优雅而安全的方式将其形式化。
ArrayBlockQueue
LinkedBlockQueue
线程安全的集合
ConcurrentHashMap
ConcurrentSkipListMap
ConcurrentSkipListSet
ConcurrentLinkedQueue
在java以前版本中,Vector和HashTable提供了线程安全,在1.2中这些类被弃用,取而代之的是ArrayList和HashMap,这些类不是线程安全的,而集合库中提供了不同的机制,通过使用同步包装器变成线程安全的
Collections.synchronizedList(new ArrayList)
Collections.synchronizedMap(new HashMap)
Callable与Future
FutureTask包装器是一种非常便利的机制,可以将Callable转换为Future和Runnable
Callable<Integer> myComputation = …
FutureTask<Integer> task = new FutureTask<Integer>(myComputation);
Thread t = new Thread(task);//it is a Runnable
t.start();
…
Integer result = task.get();//it is future
执行器
Executors中有newCachedThreadPool,newFixedThreadPool,newSingleThreadExecutor
还有预定执行,newScheduledThreadPool
同步器
1.倒计时门栓CountDownLatch
一次性的,一旦计数为0,就不能再重用