进程(Process):一个进程有自己的执行环境以及执行变量。
线程(Thread):共享执行环境以及变量。
多线程(Multithreading):一个程序同时运行一个以上的线程就称为多线程程序, 所有java程序都至少有一个线程--主线程(main thread),所有的线程都是直接或间接的由主线程创建。
Java提供两种编程式的方式声明线程
1、继承java.lang.Thread 类
2、实现java.lang.Runnable 接口
Thread Or Runnable?
如果的你代码已经继承了其他的类,那么你只能去实现Runnable接口,因为java只支持单继承但却支持多接口实现。
线程的5种状态
New:创建一个新线程
通过new关键字创建一个新的线程,这个线程的状态就是New状态,在这个状态下这个线程并不是活动中的。
Runnable:可运行状态
当你调用了一个线程的start()方法时,这个线程的状态就变成了可运行状态,并且的他的控制权已经交由线程调度器(Thread Scheduler)来接管,是否立即运行这个线程或者是让他在可运行线程池等一会在运行取决于操作系统的线程调度器。
Running:运行状态
当一个线程被执行的时候,他的状态就处于运行状态。线程调度器从可运行线程池中捞一个线程出来把他的状态变更为运行中,CPU就开始执行这个线程。一个运行中状态根据操作系统的时间片调度,状态可能会变更为Runnable(可运行),Blocked(阻塞)或者是Dead(消亡)
Blocked/Waiting:阻塞/等待状态
一个运行中线程可能会因为调用thread.join方法或者需要等待某些必须的资源,可能会导致他进入这种状态,一旦获取到了相应的资源那么他的状态就会从Blocked/Waiting状态变更到Runnable状态等待继续执行。
Dead:消亡状态
一旦一个线程执行完毕,他的状态就会变为消亡状态。
常用方法介绍:
Thread.sleep()
Thread.sleep()方法通知线程调度器把当前线程状态调整至等待状态一段时间,一旦时间等待完毕之后这个线程的状态就会变为可运行状态等待CPU执行
需要注意的是你传入该方法的等待时间参数并不一定是你线程等待的时间,这个时间只是waiting状态的时间,实际上你的线程实际等到的时间应该是waiting time + runnable time的时间,加入你的CPU执行比较空闲的时间那么实际等待的时间就会十分接近你的
waiting状态的时间
Thread.join()
join方法能将当前运行的线程阻塞,直到被指定调用join的线程消亡
比如在主线程main方法中调用了一个线程的join
pseudo code: main { .... Thread t1 = new Thread(); t1.start(); t1.join(); .... }
主线程创建了一个名为t1的线程,那么在该程序里有两个线程在同时运行一个是主线程main另一个是线程t1,在主线程的代码中线程t1调用join()方法,那么此时主线程就需要等待t1线程执行完毕他才能运行。
Sleep and JoinSleep是静态方法,是类级别的,作用是让当前线程阻塞
Join目的是让线程同步,如果在t线程中调用t1.join表示当t1线程执行完之后再执行t线程
wait,notify,notifyAll
在Object类的方法中,有这么三个方法用于在线程在资源锁状态上进行通信,如果一个线程对一个对象调用了这三个方法,那么这个线程就必须持有这个对象的监视器(Monitor),否则的话就会抛出 java.lang.IllegalMonitorStateException异常.
wait
wait共有三个重载的方法,如果在一个对象锁中调用wait方法,当前线程会休眠并且释放锁资源等待其他线程调用notify或者notifyAll方法才能继续执行,这点与Sleep不同,Sleep只会休眠但不会释放对象锁资源
notify
notify方法只会唤醒一个等待资源对象的线程,如果有多个线程同时都在等待被唤醒,那么唤醒的哪个对象则取决于操作系统。
notifyAll
notifyAll会唤醒所有等待资源的对象,哪个先执行则取决于操作系统
Java Thread(一) Outline