a.线程
b.进程
a.分时调度(轮流)
b.抢占式调度(抢)
a.同步
b.异步
a.并发
b.并行
继承Thread、重写run()
public class MyThread extends Thread{ /** * run方法就是线程要执行的任务方法 */ @Override public void run() { //这里的代码,就是一条新的执行路径 //这个执行路径的触发方式,不是调用run方法,而是通过thread对象的start()来启动任务 for (int i=0;i<10;i++){ System.out.println("我是本线程要执行的任务"+i); } } }
创建继承Thread的类对象,使用start()启动线程
public class ThreadDemo { public static void main(String[] args) { //Thread MyThread m = new MyThread(); m.start(); for (int i=0;i<10;i++){ System.out.println("我是主线程的任务"+i); } //每个线程都拥有自己的栈空间,共用一份堆内存 m.run(); //常用Thread类构造方法 //Thread() //Thread(Runnable),一参传一个任务 //Thread(Runnable,name),二参,一个传一个任务,一个传线程名字 //常用的Thread类方法 //getName //getId //getPriority 获取线程优先级 //setPriority 设置线程优先级 //关于线程优先级 有三个常量 大、小、默认 //start //stop 已过时 方法不安全 //结束线程 可以 声明一个变量来标记 变量改变则结束线程 //sleep(1000) 休眠 暂时停止 //上面是线程休眠1s的方法 //setDaemon 标记 守护线程 或 用户线程 //守护线程:守护线程不能控制自己的生命,守护线程依附于用户线程,用户线程结束,守护线程自动死亡 //用户线程:用户线程即不管是mian线程还是子线程未执行结束 程序都不会结束的线程 都称为用户线程 //mian线程是主线程,其他为子线程 } }
实现Runnable接口,重写run()
public class MyRunnable implements Runnable{ @Override public void run() { for (int i=0;i<10;i++){ System.out.println(i+"床前上天窗"); } } }
创建任务对象,创建线程并分配任务,start()启动线程
public class RunnableDemo { public static void main(String[] args) { //实现Runnable //1. 创建任务对象 MyRunnable r = new MyRunnable(); //2. 创建一个线程,并为其分配一个任务 Thread t = new Thread(r); //3. 执行这个线程 t.start(); for (int i=0;i<10;i++){ System.out.println("底下没有光"+i); } //这里是创建匿名Thread对象 的方式创建一个一次性线程 new Thread(){ @Override public void run() { for (int i=0;i<10;i++){ System.out.println("匿名类一次性线程"+i); } } }.start(); } }
实现Runnable 与 继承Thread相比的优势:
1. 通过创建任务,然后给线程分配的方式来实现的多线程。更适合多个线程同时执行相同任务的情况 2. 可以避免单继承所带来的局限性 3. 任务与线程本身是分离的,提高了程序的健壮性 4. 后线程池技术,接受Runnable类型的任务,不接受Thread类型的线程
有返回值的线程Callable
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class MakeThreadByCallable { public static void main(String[] args) throws InterruptedException, ExecutionException { Callable<Integer> c = new MyCallable(); FutureTask<Integer> task = new FutureTask<>(c); new Thread(task).start(); /** * task.isDone(); //判断子线程是否执行完毕 * task.cancel(); //参数为布尔类型的 */ int callableNum = task.get(); System.out.println("----------------"); System.out.println(callableNum); System.out.println("----------------"); for (int i=0;i<10;i++){ Thread.sleep(100); System.out.println(Thread.currentThread().getName()+i); } } static class MyCallable implements Callable<Integer>{ @Override public Integer call() throws Exception { for (int i=0;i<10;i++){ Thread.sleep(100); System.out.println(Thread.currentThread().getName()+i); } return 100; } } }
CachedThreadPool:缓存线程池(长度无限制)
任务加入后的执行流程:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CachedThreadPoolDemo { public static void main(String[] args) throws InterruptedException { //指挥线程池执行新的任务 ExecutorService service = Executors.newCachedThreadPool(); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":锄禾入党无"); } }); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":旱地核下土"); } }); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":清名上河图"); } }); Thread.sleep(2000); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":旱地核下土"); } }); } }
FixedThreadPool:定长线程池(长度是指定任务的数值)
任务加入后的执行流程:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FixedThreadPoolDemo { public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(2); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":锄禾入党无"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } }); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":旱地核下土"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } }); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":清名上河图"); } }); } }
SingleThreadExecutor:单线程线程池
执行流程:
package ThreadTrain; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class SingleThreadExecutorDemo { public static void main(String[] args) { ExecutorService service = Executors.newSingleThreadExecutor(); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":老子是你儿子"); } }); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":儿子我是你爹"); } }); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":老儿我是你爷"); } }); } }
ScheduledThreadPool:定长线程池(周期任务)
执行流程:
周期性任务执行时:
package ThreadTrain; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledThreadPoolDemo { public static void main(String[] args) { ScheduledExecutorService service = Executors.newScheduledThreadPool(2); /** * 方式一 定时执行一次 * 参数1. 定时执行的任务 * 参数2. 时长数字 * 参数3, 时长数字的时间单位,TimeUnit的常量指定 service.schedule(new Runnable() { @Override public void run() { System.out.println("你好兄弟"); } },5, TimeUnit.SECONDS);*/ /** * 周期性执行任务 * 参数1. 任务 * 参数2. 延迟时长数字(第一次执行在什么时间以后) * 参数3. 周期时长数字(每隔多久执行一次) * 参数4. 时长单位数字 */ service.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("旱地核下土"); } },5,1,TimeUnit.SECONDS); } }