启动线程的2种方式
1、继承Thread类,重写run方法class A extends Thread{ @Override public void run() { super.run(); }}new A().start();2、实现Runnable接口,重写run方法class A implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()); }}new Thread(new A()).start();
线程的声明周期

1、新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();2、就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;3、运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;4、阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:(1)等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;(2)同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;(3)其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。就绪状态转换为运行状态:当此线程得到处理器资源;运行状态转换为就绪状态:当此线程主动调用yield()方法或在运行过程中失去处理器资源。运行状态转换为死亡状态:当此线程线程执行体执行完毕或发生了异常。此处需要特别注意的是:当调用线程的yield()方法时,线程从运行状态转换为就绪状态,但接下来CPU调度就绪状态中的哪个线程具有一定的随机性,因此,可能会出现A线程调用了yield()方法后,接下来CPU仍然调度了A线程的情况。
start()
主线程执行start(),请求jvm,启动新线程,线程调度,有空闲则执行。准备工作:就绪状态。不能重复调用start()方法,会抛出IllegalThreadStateException异常。start()方法会使得该线程开始执行;java虚拟机会去调用该线程的run()方法。最终执行c++的start0()方法。private native void start0();不可以重复调用start()方法。
run()
这只是一个普通的方法。和普通的方法没有区别。所以启动线程,要调用start()方法,然后间接的调用run()方法。当通过实现Runnable接口来创建线程时,启动线程会使得run()方法在那个独立执行的线程中被调用。
sleep()
睡眠。将线程挂起一段时间。时间自己指定。该方法不占用CPU,并且规定时间过后自动复活线程。
yield()
一个线程在运行,另外一个线程也在运行。CPU层级执行线程,有一个等待队列。中间调用该方法,离开一会,进入CPU等待队列。该方法可理解为,让出cpu,给其他线程执行,当然也可能继续执行(因为又轮到它了),这要看调度算法。
join()
在本线程里调用本线程的join方法是没有意义的
比如,2个线程,A和B
A线程,执行到中途某个位置,调用了B.join()。
此时,会将B线程加入到A线程,A线程停住,执行完B线程,
再讲A线程剩下的内容执行完。
该方法经常用来等待另一个线程的结束。
也就是等B线程运行结束,A线程才运行完。再比如保证线程的执行顺序等等。
interrupt()
停止线程
使用thread.interrupt();
//这个是真正的中断方法
private native void interrupt0();
配合thread.isInterrupted()使线程中断。
该方法用于检测线程是否中断,是返回true,否返回false。