线程在一定条件下,状态会发生变化。线程变化的状态转换图如下:
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方法
休眠被打断