您的位置:首页 > 其它

线程的创建终止和生命周期

2016-07-17 14:28 260 查看
1 线程的创建

方法1:实现Runnable接口(推荐)

class Runner1 implements Runnable {
public void run() {
for(int i=0; i<30; i++) System.out.println("No. " + i);
}
}
public class TestThread1 {
public static void main(String args[]) {
Thread t1 = new Thread(new Runner1());
t1.start();
}
}


Runable是任务的概念,如果我们直接这样写,会怎么样呢?只会在原来的线程(Main的)里执行run方法。可见Runable更灵活,任务不用写死在线程里,可以放到不同的线程,甚至线程池里运行。把任务和运行分离。

public class TestThread1 {
public static void main(String args[]) {
Runnable r1 = new Runner1();
r1.run();
}
}


方法2:继承Thread

class Thread1 extends Thread {
public void run() {
for(int i=0; i<100; i++) {
System.out.println("Runner1 :" + i);
}
}
}
public class TestThread1 {
public static void main(String args[]) {
Thread1 t1 = new Thread1();
t1.start();
}
}


2 线程的终止

参考:http://www.cnblogs.com/skywang12345/p/3479949.html
http://hapinwater.iteye.com/blog/310558
  线程的终止主要有三种方式:

  a. interrupt;

  b. 通过额外标识位;

  c. suspend(暂停),resume(恢复),stop(终止),这三个方法已经过时。suspend和resume就像唱片机,能停能恢复,现在主要被wait/notify取代。stop终止线程太暴力,没时间让线程释放资源,所以被淘汰了。

  这些终止是让别的线程终止自己,因别人启动,因别人终止啊~。要终止自己只要从run方法return就行。

2.1 interrupt

每个线程上都有一个标识位interrupted,说明该线程是否被中断。当interrupt()时,只会改标志位,不会真的终止线程。我这里加了一个on标识来关掉这个线程,否则我们就没办法关闭它了。

class ATask  extends Thread {
private volatile boolean on=true;

public void run() {
while (on) {
System.out.println("I am running!");
for (int i = 0; i < 10000000; i++);
}
}

public void shutdown(){
on=false;
}
}

public class TestThread {

public static void main(String[] args) throws Exception{
ATask t = new ATask();
t.start();

//运行一断时间中断线程
Thread.sleep(20);
System.out.println("****************************");
System.out.println("Interrupted Thread!");
System.out.println("****************************");
t.interrupt();
Thread.sleep(20);
System.out.println("ShutDown Thread!");
System.out.println("****************************");
t.shutdown();
}
}


运行结果:

I am running!
I am running!
****************************
Interrupted Thread!
****************************
I am running!
I am running!
ShutDown Thread!
****************************


  interrupted可以通过myThread.isInterrupted()查询,也可以通过Thread.interrupted()重置interrupted标志位(设为fasle)。

  java给了线程编写者自由,让他定义在别人中断自己时怎么响应。主要分两种情况,一种是阻塞式的,另一种是非阻塞式。

a. 阻塞式的:调用了sleep(), wait(), join()等方法就会进入阻塞状态。就是说干什么已经不由线程编写者决定,控制权交到sleep里。这些阻塞方法都会抛InterruptedException异常,我么只要在catch里响应Interrupt。可以向下面乖乖地return,就终止了线程(并释放相应资源);也可以直接不管(catch里什么都不写),这样线程就会继续while下去。这里有个小细节,在抛InterruptedException时,虚拟机会重置interrupted标志位。

class ATask  extends Thread {
public void run() {
while(true){
try {
System.out.println("I am running!");
sleep(1000);
} catch (InterruptedException e) {
System.out.println("ATask.run() interrupted!");
return;
}
}
}
}

public class TestThread {
public static void main(String[] args) throws Exception{
//将任务交给一个线程执行
Thread t = new ATask();
t.start();

//运行一断时间中断线程
Thread.sleep(20);
System.out.println("****************************");
System.out.println("Interrupted Thread!");
System.out.println("****************************");
t.interrupt();
}
}


运行结果:

I am running!
****************************
Interrupted Thread!
****************************
ATask.run() interrupted!


b. 非阻塞式方法:不是阻塞式的,控制权在自己手里。

class ATask  extends Thread {
public void run() {
//检查程序是否发生中断
while (!Thread.interrupted()) {
System.out.println("I am running!");
for (int i = 0; i < 1000000; i++);
}
System.out.println("ATask.run() interrupted!");
}
}
public class TestThread{

public static void main(String[] args) throws Exception{
//将任务交给一个线程执行
Thread t = new ATask();
t.start();

//运行一断时间中断线程
Thread.sleep(20);
System.out.println("****************************");
System.out.println("Interrupted Thread!");
System.out.println("****************************");
t.interrupt();
}
}


运行结果:

I am running!
I am running! **************************** Interrupted Thread! **************************** ATask.run() interrupted!


2.2 通过额外标识位

class ATask  extends Thread {
private volatile boolean on = true;

public void run() {
while(on){
System.out.println("I am running!");
for (int i = 0; i < 10000000; i++);
}
}

public void shutDown() {
on = false;
}
}

public class TestThread {
public static void main(String[] args) throws InterruptedException{
//将任务交给一个线程执行
ATask t = new ATask();
t.start();

//运行一断时间中断线程
Thread.sleep(20);
System.out.println("****************************");
System.out.println("shutDown Thread!");
System.out.println("****************************");
t.shutDown();
}
}


对比2.1,2.2两种方法:

a 都能 自由地处理其他线程的终止请求;

b 都能 在终止时释放资源;

c 2.2不能终止处于阻塞状态的线程。

3 线程的生命周期



线程的状态起始很简单,就是启动->运行->终止。等待,超时等待,阻塞都是一种阻塞状态,到用到时在分析,和线程的状态没太多关系,就那么简单。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: