1. 线程的创建和启动
1.1 继承Thread
在run方法里,通过this获取当前线程。
多个线程不能共享实例变量。
1.2 通过实现接口
1.2.1 实现Runable接口
在run方法里,只能通过Thread.currentThread()获取当前线程。
多个线程可以共享实例变量。
1.2.2 使用Callable和Future
call()方法比run()方法更强大:
1. call()方法可以有返回值。
2. call()方法可以声明抛出异常。
注意:
- Callable对象不能直接作为Thread的target
- FutureTask类实现了Future接口和Runable接口,可以作为Thread的target
2. 线程的生命周期
- new new一个thread
- ready 调用start()
- run
- blocked
- terminated
- run()或call()方法正常结束
- 线程抛出Exception或Error
- 直接调用线程的stop()——容易导致死锁
当主线程结束时,其他线程不会受到影响,并不会随之结束。一旦子线程启动起来后,它就有和主线程相同的地位,它不会受主线程的影响。
3. 线程控制
3.1 join线程
调用者被阻塞,知道被调用线程执行完,调用者才会继续执行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class JoinThread extends Thread{ public JoinThread(String name){ super(name); } public void run(){ for(int i=0;i<100;i++){ System.out.println(getName() + " " + i); } } public static void main(String[] args) throws Exception { new JoinThread("新线程").start(); for(int i=0;i<100;i++){ if(i == 20){ JoinThread jt = new JoinThread("被join的线程"); jt.start(); //main线程调用了jt线程的join()方法,main线程必须等待 //jt执行结束之后才会向下执行 jt.join(); } System.out.println(Thread.currentThread().getName() + " " + i); } } }
3.2 后台线程
如果所有前台线程死亡,后台线程自动死亡。
前台线程创建的子线程,默认是前台线程。后台线程创建的子线程,默认是后台线程。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 JoinThread jt = new JoinThread("被join的线程"); 2 jt.setDaemon(true); 3 jt.start();
3.3 线程睡眠
Thread.sleep(3000);
3.4 线程让步
Thread.yield();
3.5 改变线程优先级
Thread.setPriority();
4. 线程同步
4.1 同步块synchronized statements
4.2 同步方法synchronized methods
单线程:StringBuilder
多线程:StringBuffer
同步方法,只对同一实例有效果,同一个类的不同实例的同一方法,是没有作用的。
4.3 同步监视器的释放
- 释放
- 当前线程的同步代码块和同步方法执行结束
- 当前线程,遇到了break、return终止了同步代码块和同步方法的执行
- 当前线程执行时,遇到了Error或Exception,异常结束时
- 当前线程执行同步代码块或同步方法时,程序调用了同步监视器的wait()方法
- 不释放
- 程序调用Thread.sleep()、Thread.yield()
- 其他线程调用当前线程的suspend()方法将当前线程挂起
4.4 同步锁
根接口:Lock、ReadWriteLock
实现类:ReentrantLock、ReentrantReadWriteLock、StampedLock
4.5 死锁
java虚拟机不检测死锁,也没有措施
5. 线程通信
5.1 传统
- wait()
- notify()
- notifyAll()
5.2 Lock and Condition
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private final Lock lock = new ReentrantLock(); private final Condition cond = lock.newCondition(); ... cond.await(); cond.signal(); cond.signalAll();
5.3 BlockingQueue
6. 线程组
ThreadGroup
7. 线程池
- Executors
- ForkJoinPool
8. 线程相关类
8.1 ThreadLocal类
复制资源,不同的线程拥有不同的副本。
8.2 包装线程不安全的集合
HashMap m = Collections.synchronizedMap(new HashMap());
8.3 线程安全的集合
在java.util.concurrent包下
- Concurrent开头
- ConcurrentHashMap
- ConcurrentSkipListMap
- ConcurrentSkipListSet
- ConcurrentLinkedQueue
- ConcurrentLinkedDeque
- CopyOnWtrite开头
- CopyOnWriteArrayList
- CopyOnWriteArrayset