第一章 Java多线程技能
- 进程和多线程的概念及线程的优点
- 进程
- 进程是操作系统结构的基础;是一次程序的执行;是一个程序及其数据在处理机上顺序执行时发生的活动;是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个基本单位。windows任务管理器中每一个运行的exe程序就可以理解为一个进程。
- 什么是线程
线程可以理解为是在进程中独立运行的子任务。比如QQ.exe运行时就有很多的子任务在同时运行。比如好友视频线程、下载文件线程、传输数据线程、这些不同的功能或任务可以同时运行,其中每一项任务完全可以理解为一个线程在工作。使用多线程有什么优点?可以最大限度地利用CPU的空闲时间来处理其他的任务。
- 停止线程
- 不可以使用Thread.stop()方法,因为不安全,并且已经过时
- 大多数停止一个线程的操作使用Thread.interrupt()方法,但这个方法不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的终止。
- java中有三种方法可以终止正在运行的线程
- 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止
- 使用Stop方法强行终止线程,但是不推荐使用这个方法
- 使用interrupt方法中断线程。
- 调用interrupt方法仅仅是在当前线程打了一个停止的标记,并不是真的停止线程。
- 判断线程是否是停止状态
- interrupted()方法:测试当前线程是否已经中断,静态方法,执行后具有将状态标志置清除为false的功能。
- isInterrupted():测试线程Thread对象是否已经中断,但不清除状态标记。
- 在sleep中被停止会进入catch语句,并且清楚停止状态值,使之变为false。
- 为什么不能用stop方法
- 强制停止线程有可能使一些清理性的工作得不到完成。
- 对锁定的对象进行了“解锁”导致数据得不到同步的处理,造成数据不一致的问题。
- 还可以使用return,不过还是建议用抛异常的方法来实现线程的停止。
- 暂停线程
- suspend方法暂停线程,resume方法恢复线程的执行
- 缺点:独占公共的同步对象,使其他线程无法访问同步对象。也容易出现因为线程的而暂停而导致数据不同步的情况。
- yield方法:放弃当前的cpu资源,将它让给其他任务去占用CPU执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得cpu时间片。
- setPriority方法用于设置线程的优先级
- 继承性:A线程启动B线程,那么B线程和A线程的优先级是一样的
- 规则性:CPU尽量把执行资源让给优先级比较高的线程
- 随机性:优先级较高的线程不一定每一次都能先执行完
- 守护线程
- 当进程中不存在非守护线程了,则守护线程自动销毁。典型的守护线程就是垃圾回收线程,当进程中没有非守护线程了,则垃圾回收线程也没有存在的必要了。
第二章 对象及变量的并发访问
- 可重入锁 :自己可以再次获取自己的内部锁,可重入锁也支持在父子类继承的环境中,子类是可以通过“可重入锁”调用父类的同步方法的。
- 当一个线程执行的代码出现异常时,其所持有的锁会自动释放。
- 同步没有继承性,父类中的方法添加了synchronized关键字,子类的方法也要添加synchronized关键字。
第三章 线程间通信
- 出现阻塞有5种情况
- 线程第暗涌sleep方法,主动放弃占用的处理器资源
- 线程第暗涌了阻塞式IO方法,在该方法返回前,该线程被阻塞。
- 线程试图获取一个同步监视器,但该同步监视器正被其他线程持有。
- 线程等待某个通知。
- 程序调用了suspend方法将该线程挂起。此方法容易导致死锁
- 每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列。就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程。一个线程被唤醒之后,才会进入就绪队列,等待cpu的调度;反之,一个线程wait后,就会进入阻塞队列,等待下一次被唤醒。
- wait方法释放锁,notify方法不释放锁,必须执行完notify方法所在的同步synchronized代码块后才释放锁
- 当线程处于wait状态时,调用线程对象的interrupt方法会抛出异常。
- sleep也不释放锁
- 通过管道进行线程间通信:字节流
- 管道流(pipeStream)是一种特殊的流,用于在不同线程间传送数据。一个线程发送数据到输出管道,另一个线程从输入管道中读数据。
- ThreadLocal
- 通过ThreadLocal每个线程可以绑定自己的值
- ReentrantLock可以通过多个Condition来控制想要唤醒的线程。
- 公平锁和非公平锁
- 公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的
- 非公平锁就是一种获取锁的抢占机制,是随机获得锁的。
- ReentrantLock的构造参数,可以传入一个boolean值,true表示公平锁,false表示非公平锁
- ReentrantReadWriteLock 读写锁
多个读锁不排斥,读锁和写锁互斥,写锁和写锁互斥