线程概述线程是程序的多条执行路径,是执行调度的单位,依赖于进程的存在。线程不仅可以共享进程的内存,还可以拥有自己的内存空间。这个内存空间也叫线程栈,是线程创建时由系统分配的。主要用来保存线程内部使用的数据,比如线程函数中定义的变量被执行。注意:Java中的多线程是一种抢占式机制而不是分时机制。抢占机制是指有多个线程处于可运行状态,但一个CPU只允许一个线程同时运行,它们通过竞争抢占CPU。线程状态NEW(newstate):当一个线程的实例被创建时,即使用new关键字和Thread类或其子类创建一个线程对象后,此时线程处于new状态,而新状态的线程有自己的内存空间,但是线程没有运行。此时线程处于RUNNABLE(就绪状态)不存活:当新创建的线程执行Thread.start()时,线程进入就绪状态。该状态的线程已经准备好运行,但还没有真正执行run方法的代码。RUNNING(运行中):当一个处于就绪状态的线程被CPU选中并分配一个时间片开始执行时,进入运行状态。这个状态的线程实际上是在执行run方法。BLOCKED(阻塞状态):一个正在运行的线程会在两种情况下进入阻塞状态。一种是等待获取同步锁时;另一种是获取同步锁的线程调用对象后被唤醒。该状态的线程获取到锁后进入就绪状态。WAITING(等待状态):一个正在运行的线程在执行完Object.wait()、Thread.join()、LockSupport.park()等方法后会进入等待状态。处于等待状态的线程需要被其他线程唤醒(Object.notifyAll()、LockSupport.unpark()),唤醒后进入就绪状态。TIMED_WAITING(等待一定时间):一个正在运行的线程执行Thread.sleep(timeout),Object.wait(timeout),Thread.join(timeout),LockSupport.parkNanos(timeout),LockSupport.parkUntil(timeout),etc.方法进入等待状态一段时间。处于该状态的线程在等待超时或被其他线程唤醒后进入就绪状态。TERMINATED(终止状态):线程执行完毕或被异常中断后进入该状态。在此状态下,isAlive方法返回false。常用方法启动方法start()用于启动一个线程。当调用start方法时,系统会启动一个新的线程来执行用户定义的子任务。在这个过程中,需要的资源会被分配给相应的线程。run方法run()方法不需要由用户调用。通过start方法启动一个线程后,当线程获得CPU执行时间后,进入run方法体执行具体的任务。sleep方法sleep相当于让线程休眠,交出CPU,让CPU去执行其他任务。需要注意的是,sleep方法是不会释放锁的,也就是说,如果当前线程持有某个对象的锁,其他线程在sleep生效期间是无法获取该对象的synchronized锁的。yield方法调用yield方法会导致当前线程交出CPU权限,让CPU去执行其他线程。和sleep方法类似,同样不释放锁。但是yield无法控制交出CPU的具体时间。另外,yield方法只能让相同优先级的线程有机会获得CPU执行时间。yield方法将线程从RUNNING状态返回到RUNNABLE状态。join方法线程A执行完线程B的join方法后,线程A需要等待线程B执行完毕才能继续。从状态来看,A线程执行完B线程的join方法后,A线程进入WAITING或者TIMED_WAITING状态,一直等待,直到B线程进入TERMINATED状态或者等待超时,A线程将返回到RUNNABLE状态。wait方法wait方法是Object类实现的方法。线程执行该方法后进入WAITING或TIMED_WAITING状态,被其他线程唤醒或等待超时后进入RUNNABLE状态。需要注意的是调用wait方法会释放获取的锁,线程被唤醒后会进入BLOCKED状态。直到再次获取锁后才会进入RUNNABLE状态。notify/notifyAll方法notify/notifyAll方法也是Object类实现的方法。执行该方法后,可以唤醒等待队列中的一个/所有线程,让其进入RUNNABLE状态。
