本文已参与「新人创作礼」活动,一起开启掘金创作之路。
术语解释
- 程序(program)
概念:是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码。
- 进程(process)
概念:程序的一次执行过程,或是正在运行的一个程序。
说明:进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域
- 线程(thread)
概念:线程又称轻量级进程,同个进程下的线程共享进程的资源。
说明:线程作为调度和执行的单位,每个线程拥独立的运行栈和程序计数器(pc),线程切换的开销小。
-
并行与并发的理解
- 并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事。
- 并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事
创建线程的方法
创建新执行线程的第一种:
执行步骤
1,定义一个类继承Thread类。
2,覆盖Thread类中的run()方法。
3,直接创建Thread的子类对象创建线程。
4,调用start( )方法,start方法有两个作用:①启动当前线程 ②调用当前线程的run( )方法
运行实例
创建新执行线程的第二种
执行步骤
- 实现Runable接口
- 覆盖其run( )方法
- 通过Thread类创建线程对象,这里假设叫做 t
- 将实现Ranable接口类作为对象传进Thread的构造函数中,如new Thread ( t)
- 最后调用start方法将线程开启执行(start中调用的是t的run方法)
实现 Runnable接口的好处:
- 将线程的任务从线程的子类中分离出来,进行了单独的封装,按照面向对象的思想将任务的封装成对象
- 避免了java单继承的局限性(java支持多实现)。所以,创建线程的第二种方式较为常用
创建新执行线程的第三种
实现Callable接口。
//1.创建一个实现Callable的实现类
class NumThread implements Callable{
//2.实现call方法,将此线程需要执行的操作声明在call()中
@Override
public Object call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
if(i % 2 == 0){
System.out.println(i);
sum += i;
}
}
return sum;
}
}
public class ThreadNew {
public static void main(String[] args) {
//3.创建Callable接口实现类的对象
NumThread numThread = new NumThread();
//4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
FutureTask futureTask = new FutureTask(numThread);
//5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
new Thread(futureTask).start();
try {
//6.获取Callable中call方法的返回值
//get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。
Object sum = futureTask.get();
System.out.println("总和为:" + sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
实现Callable接口的方式创建多线程比实现Runnable接口更强大:
- call()可以返回值的。
- call()可以抛出异常,被外面的操作捕获,获取异常的信息
- Callable是支持泛型的