Java学习笔记 多线程基础


一、线程

1.进程和线程

进程 - 主要指运行在内存中的可执行文件。
线程就是进程内部的程序流,也就是说操作系统内部支持多进程的,而每个进程的内部又是支持多线程的,线程是轻量的,新建线程会共享所在进程的系统资源,因此目前主流的开发都是采用多线程。
多线程是采用时间片轮转法来保证多个线程的并发执行,所谓并发就是指宏观并行微观串行的机制。

2.线程的创建 Thread类和Runnable接口

1、继承Thread类
java.lang.Thread类代表线程
自定义类继承Thread类并重写run方法,然后创建该类的对象调用start方法。

//使用继承加匿名内部类的方式 显式创建线程

 new Thread() {
            @Override
            public void run() {
                System.out.println("张三说:在吗?");
            }
        }.start();

2、继承Runnable接口
自定义类实现Runnable接口并重写run方法,创建该类的对象作为实参来构造Thread类型的对象,然后使用Thread类型的对象调用start方法。

public class RunnableIdNameTest implements Runnable {
    @Override
    public void run() {
        // 获取当前正在执行线程的引用,也就是子线程的引用
        Thread t1 = Thread.currentThread();
        System.out.println("子线程的编号是:" + t1.getId() + ", 名称是:" + t1.getName()); // 14 guanyu
        t1.setName("zhangfei");
        System.out.println("修改后子线程的编号是:" + t1.getId() + ", 名称是:" + t1.getName()); // 14 zhangfei
    }

    public static void main(String[] args) {

        RunnableIdNameTest rint = new RunnableIdNameTest();
        //Thread t2 = new Thread(rint);
        Thread t2 = new Thread(rint, "guanyu");
        t2.start();

        // 获取当前正在执行线程的引用,当前正在执行的线程是主线程,也就是获取主线程的引用
        Thread t1 = Thread.currentThread();
        System.out.println("主线程的编号是:" + t1.getId() + ", 名称是:" + t1.getName());
    }
}

3、线程的创建 Callable接口

从Java5开始新增加创建线程的第三种方式为实现java.util.concurrent.Callable接口。

java.util.concurrent.FutureTask类用于描述可取消的异步计算,该类提供了Future接口的基本实现,包括启动和取消计算、查询计算是否完成以及检索计算结果的方法,也可以用于获取方法调用后的返回结果。

public class ThreadCallableTest implements Callable {

    @Override
    public Object call() throws Exception {
        // 计算1 ~ 10000之间的累加和并打印返回
        int sum = 0;
        for (int i = 1; i <= 10000; i++) {
            sum +=i;
        }
        System.out.println("计算的累加和是:" + sum); // 50005000
        return sum;
    }

    public static void main(String[] args) {

        ThreadCallableTest tct = new ThreadCallableTest();
        FutureTask ft = new FutureTask(tct);
        Thread t1 = new Thread(ft);
        t1.start();
        Object obj = null;
        try {
            obj = ft.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("线程处理方法的返回值是:" + obj); // 50005000
    }
}

4、线程常用的方法

在这里插入图片描述
Object类中有关线程的方法
在这里插入图片描述

二、线程池

线程池相关类和方法

从Java5开始提供了线程池的相关类和接口:java.util.concurrent.Executors类和java.util.concurrent.ExecutorService接口。
其中Executors是个工具类和线程池的工厂类,可以创建并返回不同类型的线程池,常用方法如下:
在这里插入图片描述
其中ExecutorService接口是真正的线程池接口,主要实现类是ThreadPoolExecutor,常用方法如下:
在这里插入图片描述

线程池创建 代码示例

public class ThreadPoolTest {

    public static void main(String[] args) {

        // 1.创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 2.向线程池中布置任务
        executorService.submit(new ThreadCallableTest());
        // 3.关闭线程池
        executorService.shutdown();
    }
}

三、线程的生命周期

在这里插入图片描述
新建状态 - 使用new关键字创建之后进入的状态,此时线程并没有开始执行。
就绪状态 - 调用start方法后进入的状态,此时线程还是没有开始执行。
运行状态 - 使用线程调度器调用该线程后进入的状态,此时线程开始执行,当线程的时间片执行完毕后任务没有完成时回到就绪状态。
消亡状态 - 当线程的任务执行完成后进入的状态,此时线程已经终止。
阻塞状态 - 当线程执行的过程中发生了阻塞事件进入的状态,如:sleep方法。阻塞状态解除后进入就绪状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值