Java多线程
Java多线程
程序、进程和线程
一、程序
- 程序是存储在磁盘上, 包含可执行机器指令和数据的静态实体。 即进程或者任务是处于活动状态的计算机程序。
二、进程
-
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例,即运行中的程序。
-
一个运行着的程序,可能有多个进程。进程在操作系统中执行特定的任务。
-
程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
三、 线程
- 线程就是程序的执行路线,即进程内部的控制序列,或者说是进程的子任务。
- 线程,轻量级,不拥有自己独立的内存资源,共享进程的代码区、数据区、堆区(注意没有栈区)、环境变量和命令行参数、文件描述符、信号处理函数、当前目录、用户ID和组ID等资源。
- 线程拥有自己独立的栈,因此也有自己独立的局部变量。
- 一个进程可以同时拥有多个线程,即同时被系统调度的多条执行路线,但至少要有一个主线程。
总结
- 线程就是独立的执行路径;
- 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程;
- main()称之为主线程,为系统的入口,用于执行整个程序;
- 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与
- 操作系统紧密相关的,先后顺序是不能认为的干预的。
- 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;
- 线程会带来额外的开销,如cpu调度时间,并发控制开销。
- 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致
线程实现
继承Thread类
线程是程序中执行的线程。Java虚拟机允许应用程序同时运行多个执行线程。
每个线程都有优先权。 具有较高优先级的线程优先于具有较低优先级的线程执行。 每个线程可能也可能不会被标记为守护进程。 当在某个线程中运行的代码创建一个新的
Thread
对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护进程线程。当Java虚拟机启动时,通常会有一个非守护进程线程(通常调用某个指定类的名为
main
的方法)。 Java虚拟机继续执行线程,直到发生以下任一情况:
- 已调用类
Runtime
的exit
方法,并且安全管理器已允许执行退出操作。- 通过调用
run
方法返回或抛出超出run
方法传播的异常,所有非守护程序线程的线程都已死亡。
创建线程方式一:继承Thread类,重写run()方法,调用start()开启线程
public class MyThread extends Thread{ @Override public void run() { //子线程方法 for (int i = 0; i < 20; i++) { System.out.println("我是子线程" + i); } } public static void main(String[] args) { //开启子线程 new MyThread().start(); for (int i = 0; i < 20; i++) { System.out.println("我是主线程" + i); } } }
执行结果
可以发现,主线程和子线程是”同时“进行的。
Thread类实现了Runnable接口,内部通过静态代理调用了run()方法
实现Runnable接口
public class MyThread implements Runnable{ @Override public void run() { //子线程方法 for (int i = 0; i < 20; i++) { System.out.println("我是子线程" + i); } } public static void main(String[] args) { //创建线程对象,代理线程 new Thread(new MyThread()).start(); for (int i = 0; i < 20; i++) { System.out.println("我是主线程" + i); } } }
使用方法基本和继承Thread类相同,执行结果也相似。
实现Callable接口
- 实现Callable接口,需要返回值类型
- 重写call方法,需要抛出异常
- 创建目标对象
- 创建执行服务: ExecutorService ser = Executors.newFixedThreadPool(1);
- 提交执行: Future<Boolean> result1 = ser. submit(t1);
- 获取结果: boolean r1 = result1.get()
- 关闭服务: ser. shutdownNow();
示例代码
public class MyThread implements Callable<Boolean> { @Override public Boolean call() { //子线程方法 System.out.println("执行了子线程"); return true; } public static void main(String[] args) throws ExecutionException, InterruptedException { MyThread t1 = new MyThread(); //创建执行服务 ExecutorService ser = Executors.newFixedThreadPool(1); //提交执行 Future<Boolean> result1 = ser.submit(t1); //获取结果 boolean r1 = result1.get(); //关闭服务 ser. shutdownNow(); } }