一、概述:
-
多任务操作系统: 同时可以执行多个程序
-
进程:运行中的程序(内存),进程用于向操作系统申请资源(内存、CPU、网络等)。
-
线程:进程中的执行单元(执行流),线程拥有自己独立的堆栈空间,程序计数器和自己的局部变量,不能拥有系统资源,需要和父进程及其他线程共享系统资源;同时进行的不同任务。
二、线程的创建
java中的线程类,必须是java.lang.Thread类及其子类
线程任务也称为线程执行体
2.1 继承Thread
自定义一个类继承了Thread类,这个自定义类就是一个线程类,而由这个类实例化的对象就是一个线程对象
class MyThread extends Thread {
// 子线程的任务方法:run方法
public void run() {
for(int j=1; j<=100; j++) {
System.out.println("生成了第j=" + j + "辆汉汽车");
}
}
}
public class Demo1 {
// 主线程:主线程的任务方法时main方法
public static void main(String[] args) {
// 线程对象:由一个已存在的线程来创建
MyThread myThread = new MyThread();
// 开启线程任务
/*
对象.方法名称() 这个方法在哪个线程调动,这个方法就在哪个线程执行
start()方法表示子线程的任务在子线程执行
*/
myThread.start();
for(int i=1; i<=100; i++) {
System.out.println("生成了第i=" + i + "辆秦汽车");
}
}
}
Thread类提供了常用的API
Thread.currentThread() : 静态方法用于获取当前的线程对象
getName() : 可以获取线程对象的名称
主线程的名称默认是main,不能修改
子线程的名称默认是 Thread-0,.......
可以修改,修改方式,可以提供有参构造方法,调用父类的有参构造方法Thread(String name)
也可以使用setName(String name) 设置线程名称
2.2 实现Runnable接口
自定义一个类实现Runnable接口,这个类是一个任务类,这个任务类需要重写Runnable接口中的run方法,这个类的对象是一个任务对象,如果这个任务对象的任务需要在子线程中执行,必须依赖线程对象
class MyTask implements Runnable {
@Override
public void run() {
for(int i=1; i<=100; i++) {
System.out.println(Thread.currentThread().getName() + "----" + "生产了第i=" + i + "辆宋轿车");
}
}
}
public class Demo2 {
public static void main(String[] args) {
// 创建任务对象
MyTask myTask = new MyTask();
// 创建线程对象
Thread thread = new Thread(myTask, "子线程");
// 开启子线程对象的任务
thread.start();
for(int j=1; j<=100; j++) {
System.out.println(Thread.currentThread().getName() + "----" + "生产了第j=" + j + "辆秦轿车");
}
}
}
2.3 实现Callable接口
通过Future接口的实现类FutureTask来获取Callable接口实现类对象任务方法的返回值,FutureTask实现了RunnableFuture接口,RunnableFuture接口继承了Runnable接口和Future接口
// 实现了Callable接口的类,也是一个任务类
class MyCall implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i=1; i<=100; i++) {
sum += i;
}
return sum;
}
}
public class Demo5 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建任务对象
MyCall myCall = new MyCall();
// 创建FutureTask对象这个对象实现了RunnableFuture接口
// RunnableFuture多继承了Runnable接口和Future接口
// 在构造FutureTask对象时,可以通过构造方法将Callable接口的
// 实现对象传入
FutureTask<Integer> futureTask = new FutureTask<>(myCall);
// 创建一个线程对象
Thread thread = new Thread(futureTask);
thread.start();
// 通过get()方法来获取Callable任务方法的返回结果
if(futureTask.isDone()) {
Integer result = futureTask.get();
System.out.println(result);
}
}
}