转载地址:原文
一:简述
Java并发与多线程专栏的第一篇文章,主要介绍java多线程的一些基础知识。
二:java的线程状态
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
java线程有六种状态
1.NEW: 新生状态,线程创建了,但是没有调用start()方法,就处于这种状态
2.RUNNABLE: 可运行状态 线程调用start()方法进入该状态 该状态下可以被cpu调度
3.BLOCKED 阻塞状态,线程被synchronized锁阻塞进入该状态
4.WAITING 等待状态,线程调用wait(),join(),LockSupport.park()方法会进入该状态
5.TIMED_WAITING 有时间限制的等待状态,线程调用了 wait(timeout),sleep(timeout), join(timeout),LockSupport.parkNanos(timeout),LockSupport.parkUntil()等方法会进入该状态
6.TERMINATED 结束状态,调用stop(),destroy()等方法(因为不安全,在java8中已经删除)或者线程run()方法执行完成会进入该状态。
三: 线程的创建
1.实现Runnable 实现run()方法
public class TestThread implements Runnable { @Override public void run() { System.out.println("java多线程"); } public static void main(String[] args) { Thread thread = new Thread(new TestThread()); thread.start(); } }
2.继承Thread类 重写run()方法
public class TestThread extends Thread { @Override public void run() { System.out.println("java多线程"); } public static void main(String[] args) { TestThread thread = new TestThread(); thread.start(); } }
3.实现Callable,实现call()方法
public class TestThread implements Callable { @Override public Object call() throws Exception { System.out.println("java多线程"); return null; } public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask futureTask = new FutureTask<>(new TestThread()); futureTask.run(); //阻塞获取线程的执行结果 Object o = futureTask.get(); } }
四:线程的停止和中断
线程的停止
线程停止的方法有两种
方法一:调用stop(),destroy()等方法,直接强制停止线程,这种方式存在严重的安全问题,所以不推荐使用 并且在java8中已经被删除。
方法二:run()方法执行完成
public class TestThread implements Runnable { //通过一个volatile变量来控制线程的停止 private static volatile boolean flag = false; @Override public void run(){ while(!flag){ System.out.println("java多线程"); } } public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new TestThread()); t.start(); Thread.sleep(50); flag = true; } }
线程的中断
在java虚拟机中每个线程都有一个interrupt标识,表示线程是否中断,当线程处于WAITING或者TIMED_WAITING状态被中断的时候会抛出InterruptedException。java为中断提供了一些api,通过interrupt()方法中断线程,isInterrupted()方法可以知道线程是否被中断。
而中断标志也可以用来停止线程。
public class TestThread implements Runnable { @Override public void run(){ //可以通过修改中断标志来停止线程 while(!Thread.currentThread().isInterrupted()){ System.out.println("java多线程"); } } public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new TestThread()); t.start(); Thread.sleep(500); //修改中断标志为true t.interrupt(); } }
结果如下:
当线程处于WAITING或者TIMED_WAITING状态被中断的时候会抛出InterruptedException
结果如下:
可以看到我们调用了interrupt()方法,线程并没有停止,这是因为InterruptedException会将interrupt重置 也就是恢复成false,这是因为现在在处于WAITING或者TIMED_WAITING状态时,这时候被中断 应该交给被中断的线程自己决定是否要中断。
不需要中断的时候可以不做处理 如果我们需要中断的时候可以在处理异常的时候再次调用interrupt()方法。
代码如下:
public class TestThread implements Runnable { private static volatile boolean flag = false; @Override public void run(){ while(!Thread.currentThread().isInterrupted()){ try { Thread.sleep(1000); } catch (InterruptedException e) { //TODO 在中断前我们还可以做一些 *** 作 比如关闭资源 保存数据等 *** 作 //确定要中断线程 调用interrupt()方法 Thread.currentThread().interrupt(); e.printStackTrace(); } System.out.println("java多线程"); } } public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new TestThread()); t.start(); Thread.sleep(500); t.interrupt(); }
结果如下:
可以看出线程已经停止。
五 结束语
原文链接:原文
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)