多线程概念
多线程就是一个进程中多个任务“同时”执行
Java中的多线程是一种抢占式的机制而不是分时机制
抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行。
线程主要有以下几种状态:新建,就绪,运行,阻塞,死亡。
新建:新建线程对象,没有调用start方法
就绪:调用start方法之后,线程就进入就绪状态,线程在睡眠和挂起中恢复的时候也会进入就绪状态
运行:线程执行run方法
阻塞:线程被暂停,比如说调用sleep方法后线程就进入阻塞状态
死亡:线程执行结束,即run方法执行完毕
java中的多线程
1.线程的创建
继承Thread类或者实现Runnable接口
2.线程的启动
start
启动线程(开始回调run方法)
3.线程的结束
一个线程结束的标识是run方法结束
stop
错误的结束线程的方式(API中该方法已经过时),该方法会使得线程戛然而止,无法做一些线程结束后的操作。
interrupt
不会中断一个正在运行的线程,而是设置了线程的中断标识位isInterrupted为true,在线程受阻塞的情况下(sleep,wait,join等地方)抛出一个异常InterruptedException,并且中断状态将被清除(isInterrupted重写置为false),这样线程就得以退出阻塞的状态。
因此想要通过该方法结束线程,必须在run方法中,这样写
public class InterruptDemo {
class Thread1 extends Thread {
public Thread1(String name) {
super(name);
}
public void run() {
System.out.println(getName() + "开始执行");
while (!isInterrupted()) {
try {
for (int i = 0; i < 5; i++) {
System.out.println(getName() + "第" + i + "次执行");
sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(getName()+"被中断");
interrupt(); //由于抛出异常后会重新清除中断标志位,所以要重新将标志位置为true
}
}
System.out.println(getName() + "执行结束");
}
}
public static void main(String[] args) {
InterruptDemo interrupt = new InterruptDemo();
Thread1 t1 = interrupt.new Thread1("线程1");
t1.start();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.interrupt(); //sleep中的线程立马被唤醒
}
}
运行结果
线程1开始执行
线程1第0次执行
线程1第1次执行
线程1被中断
线程1执行结束
标识位
interrupt方法的限制比较多,最简便的方式就是将while中的判断条件用一个标志位来代替,如果想结束线程,只需要将这个标志位置置为true或者false即可。
public class EndDemo {
class Thread1 extends Thread {
private boolean isRuning = true;
public Thread1(String name) {
super(name);
}
public void run() {
System.out.println(getName() + "开始执行");
while (isRuning) {
try {
for (int i = 0; i < 5; i++) {
System.out.println(getName() + "第" + i + "次执行");
sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(getName() + "被中断");
interrupt(); // 由于抛出异常后会重新清除中断标志位,所以要重新将标志位置为true
}
}
System.out.println(getName() + "执行结束");
}
}
public static void main(String[] args) {
EndDemo end = new EndDemo();
Thread1 t1 = end.new Thread1("线程1");
t1.start();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.isRuning = false;
}
}
运行结果
线程1开始执行
线程1第0次执行
线程1第1次执行
线程1第2次执行
线程1第3次执行
线程1第4次执行
线程1执行结束