一.进程和线程
进程:进程是资源分配的基本单位,每个进程都有自己独立的内存空间,可以看作是一个正在运行的程序实例
线程:线程是CPU调度的基本单位,属于进程,一个进程可以包含多个线程。线程共享进程的内存空间和资源,但每个线程有自己独立的栈和寄存器
多进程:在操作系统中,同时运行多个程序
多进程的好处:可以充分利用CPU,提高CPU的使用率
多线程:在同一个进程(应用程序)中同时执行多个线程
多线程的好处:提高进程的执行使用率,提高了CPU的使用率
注意:
在同一个时间点一个CPU中只可能有一个线程在执行
多线程不能提高效率、反而会降低效率,但是可以提高CPU的使用率
一个进程如果有多条执行路径,则称为多线程程序
Java虚拟机的启动至少开启了两条线程,主线程和垃圾回收线程
一个线程可以理解为进程的子任务
二.线程的实现方式
1.继承Thread类
注意:
启动线程是使用start方法而不是run方法
线程不能启动多次,如果要创建多个线程,那么就需要创建多个Thread对象
class MyThread extends Thread {@Overridepublic void run() {System.out.println("Thread running by extending Thread class");}
}public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start();}
}
2.实现Runable接口
实现Runable接口的好处:
可以避免Java单继承带来的局限性
适合多个相同的程序代码处理同一个资源的情况,把线程同程序的代码和数据有效的分离,在实现解耦的同时,较好的体现了面向对象的设计思想
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("Thread running by implementing Runnable interface");}
}public class Main {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());thread.start();}
}
3.实现Callable接口
前面两种方式都是重写run方法,而run方法没有返回结果,也不能抛出异常,main方法不知道线程什么时候开启和结束,也不知道返回值。
所以在jdk1.5引入实现Callable接口的方式创建线程,即可以获取返回值,也可以抛出异常
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {return "Thread running by implementing Callable interface";}
}public class Main {public static void main(String[] args) throws Exception {FutureTask<String> futureTask = new FutureTask<>(new MyCallable());Thread thread = new Thread(futureTask);thread.start();System.out.println(futureTask.get());}
}