1.什么时候使用多线程编程
一个任务在正常情况下是按顺序执行的,但是如果当前任务里有多个相似进程块(例如for,while语句),我们就可以考虑把这些代码块抽出来并行运行,无需阻塞
2.实现多线程的几种方式
一种是继承Thread类重写run方法,另一种是实现Runnable接口重写run方法
启动多线程很多情况下是为了处理并发进程,此时对于部分实时性要求不是那么高的业务需求,我们还可以通过实现队列的方式,异步实现。
3.举例
继承Thread
/** * * @ClassName: ThreadByEx * @Description: TODO* @author Mr.jqCheng* @date 2018年9月26日 * */public class ThreadByEx extends Thread{ @Override public void run() { // TODO Auto-generated method stub System.out.println("我是继承线程"); } }
实现Runnable
/** * * @ClassName: ThreadByRunnable * @Description: TODO* @author Mr.jqCheng* @date 2018年9月26日 * */public class ThreadByRunnable implements Runnable{ /*public ThreadByRunnable() { this.run(); // TODO Auto-generated constructor stub }*/ public void run() { // TODO Auto-generated method stub System.out.println("我是实现进程"); } }
测试:
/** * * @ClassName: Test * @Description: TODO* @author Mr.jqCheng* @date 2018年9月26日 * */public class Test { public static void main(String[] args) { // 继承Thread启动的方法 ThreadByEx t1 = new ThreadByEx(); t1.start();// 启动线程 // 实现Runnable启动线程的方法 ThreadByRunnable r = new ThreadByRunnable(); Thread t2 = new Thread(r); t2.start();// 启动线程 //new ThreadByRunnable(); } }
运行结果:
我是继承线程
我是实现进程
ok,简单的多线程实现方式完成了,在调用start()的时候,该进程已经进入可执行状态,等待系统执行。
线程处理的几个常用方法:
void interrupt():向线程发送中断请求,线程的中断状态将会被设置为true,如果当前线程被一个sleep调用阻塞,那么将会抛出interrupedException异常。
static boolean interrupted():测试当前线程(当前正在执行命令的这个线程)是否被中断。注意这是个静态方法,调用这个方法会产生一个副作用那就是它会将当前线程的中断状态重置为false。
boolean isInterrupted():判断线程是否被中断,这个方法的调用不会产生副作用即不改变线程的当前中断状态。
static Thread currentThread() : 返回代表当前执行线程的Thread对象。
守护进程
用来服务于不是服务进程的其他所有当前进程下的所有线程
实现deamon.setDaemon(true)就行,要在线程开启之前启用
举例
package com.orange.util;/** * * @ClassName: Test * @Description: TODO * @author Mr.jqCheng * @date 2018年9月26日 * */public class Test { public static void main(String[] args) { Thread deamon2 = new Thread(new DaemonRunner2(), "otherRunner"); deamon2.start();// 启动线程 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Thread deamon = new Thread(new DaemonRunner(), "DaemonRunner"); // 设置为守护线程 deamon.setDaemon(true); deamon.start();// 启动线程 } static class DaemonRunner implements Runnable { public void run() { // TODO Auto-generated method stub try { Thread.sleep(300); Thread t = Thread.currentThread(); System.out.println(t); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("进入守护线程,说明现在还有其他线程在执行"); } } } static class DaemonRunner2 implements Runnable { public void run() { // TODO Auto-generated method stub try { Thread.sleep(1500); System.out.println("我是其他线程"); } catch (Exception e) { e.printStackTrace(); } } }}
执行结果:
Thread[DaemonRunner,5,main]
进入守护线程,说明现在还有其他线程在执行
我是其他线程
首先,先启动其他线程,需要耗时1500ms,同时,主线程耗时1000ms后,开始进入守护线程,此时其它线程还在运行,到了守护线程,耗时300ms,其他线程仍在执行,继续往下,守护线程执行完毕
但是如果我把守护线程的300ms改成500ms,会发生什么事呢?
出现过两种情况,毕竟在临界值
1.我是其他线程
2.Thread[DaemonRunner,5,main]
进入守护线程,说明现在还有其他线程在执行
我是其他线程
注:相关教程知识阅读请移步到JAVA教程频道。