线程在一定条件下,状态会发生变化。线程变化的状态转换图如下:
class MyThread implements Runnable{ public void run() { for (int i=1; i<=3; i++) { System.out.println(Thread.currentThread().getName()); } } } public class lzwCode { public static void main(String [] args) { MyThread my = new MyThread(); new Thread(my, "线程A").start(); new Thread(my, "线程B").start(); new Thread(my).start(); } }
说明如果我们没有指定名字的话,系统自动提供名字。
提醒一下大家:main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。
在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个jVM实习在就是在操作系统中启动了一个进程。
class MyThread implements Runnable{ public void run() { for (int i=1; i<=3; i++) { System.out.println(Thread.currentThread().getName()); } } } public class lzwCode { public static void main(String [] args) { MyThread my = new MyThread(); Thread th = new Thread(my); System.out.println("线程启动前:"+ th.isAlive()); //判断线程是否启动 th.start(); System.out.println("线程启动前:"+ th.isAlive()); } }
线程的强制执行join():
package com.demo; public class lzwCode implements Runnable{ public void run() { for (int i=1; i<=3; i++) { System.out.println(Thread.currentThread().getName()); } } public static void main(String [] args) { lzwCode my = new lzwCode(); Thread th = new Thread(my, "线程A"); th.start(); for (int i=0; i<=10; i++) { if (i > 5) { try{ th.join(); //强制执行线程th } catch(Exception e) { e.printStackTrace(); } } System.out.println("main 线程执行==>"+i); } } }
再看一个列子:
public class lzwCode implements Runnable{ private static int a = 0; public void run() { for (int i=0; i<5; i++) { a++; } } public static void main(String [] args) { Runnable my = new lzwCode(); Thread th = new Thread(my); th.start(); System.out.println(a); } }请问程序的输出结果是5吗?答案是:有可能。其实你很难遇到输出5的时候,通常情况下都不是5,几乎都是0。当然这也和机器有严重的关系。为什么呢?我的解释是当主线程main方法执行System.out.println(a);这条语句时,线程还没有真正开始运行,或许正在为它分配资源准备运行吧。因为为线程分配资源需要时间,而main方法执行完t.start()方法后继续往下执行System.out.println(a);,这个时候得到的结果是a还没有被改变的值0。怎样才能让输出结果为5!其实很简单,join()方法提供了这种功能。join()方法,它能够使调用该方法的线程在此之前执行完毕
public class lzwCode implements Runnable{ private static int a = 0; public void run() { for (int i=0; i<5; i++) { a++; } } public static void main(String [] args) { Runnable my = new lzwCode(); Thread th = new Thread(my); th.start(); try{ th.join(); } catch (Exception e){ e.printStackTrace(); } System.out.println(a); } }
这个时候,程序输入结果始终为5。
为了证明如果不使用th.join()方法,主线程main方法的System.out.println(a);语句将抢先执行,我们可以在main方法中加入一个循环,这个循环用来延长main方法执行的时间,循环次数将严重取决于机器性能。如果循环次数得当,我们也可以看到a的输出结果是5。
package com.demo; public class lzwCode implements Runnable { public static int a = 0; public void run() { for (int i = 0; i < 5; i++) { a++; } } public static void main(String[] args) throws Exception { Runnable r = new lzwCode(); Thread th = new Thread(r); th.start(); for (int i = 0; i < 300; i++) { System.out.println(i); } System.out.println(); System.out.println(a); } }
线程的休眠sleep():
public class lzwCode implements Runnable{ private static int a = 0; public void run() { for (int i=0; i<3; i++) { try { Thread.sleep(3000); //线程每隔3s执行 } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+i); } } public static void main(String [] args) { Runnable my = new lzwCode(); Thread th = new Thread(my, "线程睡觉"); th.start(); } }
【运行结果】:(结果每隔3s输出一个)
线程睡觉0
线程睡觉1
线程睡觉2
线程的中断interrupt():
public class lzwCode implements Runnable { public void run() { System.out.println("执行run方法"); try { Thread.sleep(10000); System.out.println("线程完成休眠"); } catch (Exception e) { System.out.println("休眠被打断"); return; //返回到程序的调用处 } System.out.println("线程正常终止"); } public static void main(String[] args) { lzwCode lc = new lzwCode(); Thread demo = new Thread(lc, "线程"); demo.start(); try { Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); } demo.interrupt(); //2s后中断线程 } }
【运行结果】:2秒后线程中断
执行run方法
休眠被打断