单个程序看起来在同时完成多个任务。每个任务在一个线程(thread)中执行,线程是控制线程的简称。如果一个程序可以同时运行多个线程,则称这个程序是多线程的(multithreaded)。
多进程和多线程有哪些区别?本质的区别在于每个进程都拥有自己的一套变量,而线程则共享数据。
以上摘自《JAVA 核心技术卷一》第十一版
线程
进程:正在运行的程序
线程:进程中的一条执行路径,也是CPU的基本调度单位。
在有些操作系统中,与进程相比较,线程更“轻量级”,创建、撤销一个线程比启动新进程的开销要小得多。
一个进程由一个或多个线程组成,彼此完成不同的工作,“同时执行”,称为多线程。(如果是单核的话,看着是同时执行,其实也是一个一个执行的,只是时间太快了)
进程和线程的区别:进程是操作系统资源分配的基本单位,线程是CPU的基本调度单位,一个程序运行后至少有一个进程。一个进程可以包含多个线程,至少有一个线程,否则这个进程没有意义(线程才可以执行代码)
线程的组成:
- CPU时间片:操作系统为每个线程分配执行时间
- 运行数据
- 线程的逻辑代码
线程的特点:
- 抢占式执行-效率高;可防止单一线程长时间独占CPU
创建线程的三种方式:
- 继承Thread类,重写run()方法
- 实现Runnable接口,Runnable里面只有一个方法,run()方法
- 实现Callable接口,此接口里有一个call()方法
继承Thread类方式
public class MyThread extends Thread{
//一个带参构造方法
public MyThread(String name) {
super(name);
}
Thread thread = new Thread();
@Override
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "-----" + i);
}
}
}
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread("我的线程");
myThread.start();
System.out.println(Thread.currentThread().getName() + "-----我是主线程");
}
}
Thread.currentThread().getId() //获得当前线程的id
Thread.currentThread().getName() //获得当前线程的名称
实现Runnable接口方式
public class MyThread implements Runnable{
@Override
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "-----" + i);
}
}
}
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
System.out.println(Thread.currentThread().getName() + "-----我是主线程");
}
}
实现Callable接口方式
public class Test {
public static void main(String[] args) {
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
};
//callable 不能直接作为参数传给线程,先把他转成一个任务,FutureTask实现了Runnable接口
FutureTask<Integer> futureTask = new FutureTask<>(callable);
//把任务放到线程里
Thread thread = new Thread(futureTask);
thread.start();
try {
int sum = futureTask.get();
System.out.println(sum);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (ExecutionException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
线程的状态
new(新建)
Runnable(可运行)
Blocked(阻塞)
Waiting(等待)
Time waiting(计时等待)
Terminated(终止)
调用getState方法,确定一个线程的当前状态