Java多线程基础总结线程的创建、线程状态、如何中断线程与守护线程的概念。
1、线程创建
参考Java中创建线程的方式;
2、线程暂停执行
强迫当前线程暂停一段时间, 调用Thread.sleep(time)。注意:sleep函数传入的参数是毫秒单位,并且暂停的是当前执行Thread.sleep()的线程。例如间隔1秒控制台输出:
Thread one = new Thread() { @Override public void run() { for (int i = 0; i <= 10; i++) { System.out.println(i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }; one.start();
3、线程优先级
可以对线程设定优先级,设定优先级的方法是:
Thread.setPriority(int n) // 1~10, 默认值5
注意:不可依赖线程优先级保证优先线程一定先执行。
4、线程状态
线程的状态有:
- New:新创建的线程,尚未执行;
- Runnable:正在执行的线程;
- Blocked:被阻塞的线程;
- Wating:等待中的线程;
- Timed Waiting:执行sleep方法等待中的线程;
- Terminated:线程已终止。
5、线程终止
线程终止的原因有:线程正常终止:run方法执行到return 语句返回;线程异常终止:run方法遇到未捕获的异常意外终止。
6、线程等待
线程等待指的是,当前线程等待另一个线程执行结束后,再继续运行。通常在当前线程对目标线程调用join方法,表示待目标线程运行结束后,当前线程再继续执行。join重载方法可以设置超时时间,表示过时不候。
Thread StudentThread = new Thread() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Student"); } }; Thread KongRongThread = new Thread() { @Override public void run() { StudentThread.start(); try { StudentThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Kong Rong"); } }; KongRongThread.start(); //Student //Kong Rong
上述KongRongThread线程需等待StudentThread线程执行结束后,才能继续执行。其中如果 StudentThread.join() 的参数小于1000,表示不再等待 StudentThread线程。
7、线程中断
中断线程通常对目标线程调用interrupt方法,目标线程需要反复检测自身状态是否是interrupted状态。注意:使用interrupt方法仅仅是通知目标线程进行中断,是否中断由目标线程实现逻辑。
另外,若当前线程使用join方法,正在等待目标线程执行;此时若当前线程被调用了interrupt方法,此时join方法会立刻抛出 InterruptedException。为了理解上述,抽象出老板、监工、民工三个线程示例。
Thread worker = new Thread() { @Override public void run() { for (int i = 0; i <= 10 && !isInterrupted(); i++) { System.out.println(i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); break; } } } }; Thread monitor = new Thread() { @Override public void run() { System.out.println("work start!"); worker.start(); try { worker.join(); } catch (InterruptedException e) { e.printStackTrace(); } worker.interrupt(); } }; Thread boss = new Thread() { @Override public void run() { monitor.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } monitor.interrupt(); } }; boss.start();
boss线程,3秒钟后通知 monitor线程中断,monitor负责启动worker线程,并一直等待worker线程执行;worker线程负责间隔一秒钟向控制台输出。其中对monitor调用interrupt后,monitor线程中join方法立即抛出错误。并在结束之前通知worker线程中断,work线程会一直检查 isInterrupted 状态在sleep方法报错后,结束循环。
另一个常用的中断线程的方法是设置标志位,用法与上述类似。
public volatile boolean running = true;
8、守护线程
守护线程不会影响JVM进程结束,通常为其他线程服务。
Thread t = new MyThread(); t.setDaemon(true); t.start();