线程的概念:线程是指一个操作系统能够运行、调度的最小单位,被包含在进程中,是进程的实际运作单位。
java中的创建一个线程的方式:
- 继承Thread类
- 实现Runnable接口
- 通过Callable接口和Future接口实现有返回值的线程调用(FutureTask或者CompletableFuture),还能捕获异常
通过继承Thread来实现
通过继承Runnable接口来实现
通过FutureTask来创建线程
通过CompletableFuture来实现
future.get()时线程是阻塞的,FutureTask通过for(;;). CompletableFuture通过while
如何停止一个线程
1: 主动在线程内部增加退出条件
2: 使用线程的stop方法,但是该方法已经被废弃
3: 使用interrupt:interrrupt只是给线程置一个可中断的状态,调用interrupt()方法并不会是线程中断,而是需要线程内部主动主判断中断状态,从而做中断的操作
线程的状态
初始状态:线程创建完成,但是还未调用start()方法
就绪状态:外部调用了线程的start()方法,线程变成可运行状态,进入可运行线程池中,但是还未 等到cpu使用权限,除了cpu使用权限其它的资源都已经获取到
运行状态:获取到cpu的使用权限,执行程序代码
阻塞状态:线程因为某些原因放弃cpu执行时间片,停止运行,直到线程重新进入就绪状态才有可 能转入运行状态
- 等待阻塞:线程调用wait()方法,线程释放占用的所有资源(锁等),线程进入对象的等待队列,等待被唤醒,不能自动唤醒,需要调用对象的notify或者notifyAll方法,(如果线程调用了Object的wait()方法,线程会进入该对象的等待池中,等待池的线程不会去竞争对象中的锁,当有其它线程调用了该Object的notify(随机唤醒等待池中的一个线程),或者notifyAll(唤醒所有等待池中的线程),被唤醒的线程会进入锁池,锁池的线程会去竞争Object的锁,竞争到锁的线程开始执行同步代码块的内容,未竞争到锁的线程也不会回到等待池,持有锁的线程执行完成释放锁,锁池的线程会继续竞争该Object锁)
终止状态:线程终止
线程的常用方法
wait() 和 notify() 方法与suspend() 和 resume() 方法对没有什么分别,但是事实上它们是截然不同的。区别的核心在于,前面叙述的suspend()及其它所有方法在线程阻塞时都不会释放占用的锁(如果占用了的话),而wait() 和 notify() 这一对方法则相反。