线程的启动和中断

一、线程的启动

  • extends Thread

  • implements Runnable

  • implements Callable

public class newThread {
    //1、继承Thread类
    private static class ExtendsThread extends Thread {
        public void run(){
            System.out.println("I am extends Thread");
        }
    }
    //2、implements Runnable
    private static class UseRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("I am implements Runnable");
        }
    }
    //3、implements Callable
    private static class UseCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println("I am implements Callable");
            return "Callable Return";
        }
    }
	
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExtendsThread t1 = new ExtendsThread();
        t1.start();
		
        UseRunnable useRunnable = new UseRunnable();
        Thread t2 = new Thread(useRunnable);
        t2.start();

        //启动Callable接口的实现类,需通过FutureTask来启动线程
        UseCallable useCallable = new UseCallable();
        FutureTask<String> futureTask = new FutureTask<String>(useCallable);
        futureTask.run();
        System.out.println(futureTask.get());		
    }
}

运行上述代码后的效果

二、线程的中断

停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作。

Q:怎么样才能让Java里的线程安全停止工作呢?

1)线程自然终止:

    自然执行完或抛出未处理异常

2)stop()、resume()、suspend()已不建议使用

     stop():导致线程不正确释放资源

    suspend():容易导致死锁

3)interrupt():

    它并不会直接终止掉一个正在运行的进程,而是在当前线程中,打一个需要『被停止』的标签,而是否停止应该由当前线程自己决定,所以这也决定了我们需要在编写Thread或者Runnable代码的时候,有更高的要求,要明确自己如何被安全的停止。

既然interrupt()只是为我们对当前线程做了一个简单的停止标记,而JDK同时也为我们提供了获取这个标记值的API。

  • Thread.interrupted():检查当前运行这段代码的线程,是否已经被停止。
  • this.isInterrupted():检查当前this指定的线程,是否已经被停止。

如下代码所示:

public class UseInterrupt extends Thread{
	public UseInterrupt(String threadName) {
		super(threadName);
	}
	public void run() {
		String threadName = Thread.currentThread().getName();
		while(!isInterrupted()) {
			System.out.println(threadName + " is running!");
		}
		System.out.println(threadName + " interrupt flag is "+ isInterrupted());
	}
	public static void main(String[] args) throws InterruptedException {
		UseInterrupt t = new UseInterrupt("interruptThread");
		t.start();
		Thread.sleep(50);
		t.interrupt();
	}
}

  这段代码会停止线程,但是如果将while里的判断条件,改为true,则线程将永远不会停止

public class UseInterrupt extends Thread{
	public UseInterrupt(String threadName) {
		super(threadName);
	}
	public void run() {
		String threadName = Thread.currentThread().getName();
		while(true) {
			System.out.println(threadName + " is running!");
		}
	}
	public static void main(String[] args) throws InterruptedException {
		UseInterrupt t = new UseInterrupt("interruptThread");
		t.start();
		Thread.sleep(50);
		t.interrupt();
	}
}

4)isInterrupted():

    判断当前线程是否处于中断状态

      查看isInterrupted()源码可知,isInterrupted()是Thread类提供的方法

>>> 所以,只有继承Thread类的线程类,才可直接调用isInterrupted()方法判断中断标志位是否为true

4.1) 继承Thread类实现的线程,使用isInterrupted()判断

public class UseInterrupt extends Thread{
	public UseInterrupt(String threadName) {
		super(threadName);
	}
	public void run() {
		String threadName = Thread.currentThread().getName();
		while(!isInterrupted()) {
			System.out.println(threadName + " is running!");
		}
		System.out.println(threadName + " interrupt flag is "+ isInterrupted());
	}
	public static void main(String[] args) throws InterruptedException {
		UseInterrupt t = new UseInterrupt("interruptThread");
		t.start();
		Thread.sleep(50);
		t.interrupt();
	}
}

运行上述代码后的效果:

4.2)implements Runnable类实现的线程,使用isInterrupted()判断

public class RunnableUseInterrupt implements Runnable{

	@Override
	public void run() {
		String threadName = Thread.currentThread().getName();
		while(!Thread.currentThread().isInterrupted()) {
			System.out.println(threadName+" is running!");
		}
		System.out.println(threadName+" interrupt flag is "+Thread.currentThread().isInterrupted());
	}
	
	public static void main(String[] args) throws InterruptedException {
		RunnableUseInterrupt run = new RunnableUseInterrupt();
		Thread t = new Thread(run, "runnableUseInterrupt");
		t.start();
		Thread.sleep(20);
		t.interrupt();
	}

}

运行上述代码的效果

5)方法里如果抛出InterruptedException,线程的中断标志位会被复位成false。

public class HasInterruptException {

	private static class UseThread extends Thread {
		public UseThread(String name) {
			super(name);
		}
		public void run() {
			String threadName = Thread.currentThread().getName();
			while(!isInterrupted()) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					System.out.println(threadName+" interrupt flag is "+isInterrupted());
  					e.printStackTrace();
				}
			}
			System.out.println(threadName+" interrupt flag is "+isInterrupted());
		}
	}
	public static void main(String[] args) throws InterruptedException {
		Thread endThread = new UseThread("HasInterruptEx");
		endThread.start();
		Thread.sleep(500);
		endThread.interrupt();
	}
}

此段代码运行后,线程永远不会被退出,即使调用了interrupt()方法,也不会停止线程。

如果确实是需要中断线程,要求我们自己在catch语句块里再次调用interrupt()

public class HasInterruptException {

	private static class UseThread extends Thread {
		public UseThread(String name) {
			super(name);
		}
		public void run() {
			String threadName = Thread.currentThread().getName();
			while(!isInterrupted()) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					System.out.println(threadName+" interrupt flag is "+isInterrupted());
  					e.printStackTrace();
  					interrupt();
				}
			}
			System.out.println(threadName+" interrupt flag is "+isInterrupted());
		}
	}
	public static void main(String[] args) throws InterruptedException {
		Thread endThread = new UseThread("HasInterruptEx");
		endThread.start();
		Thread.sleep(500);
		endThread.interrupt();
	}
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值