0
点赞
收藏
分享

微信扫一扫

【多线程】 - 实现方法以及自定义线程池

概念

进程

进程是程序的基本执行实体

线程

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

多个线程组成了多线程

多线程应用场景

  • 软件中的耗时操作
  • 拷贝、迁移大文件
  • 加载大量的资源文件

想让多个事情同时运行就需要多线程

并发和并行

并发

在同一时刻,有多个指令在单个CPU上交替执行

并行

在同一时刻,有多个指令在多个CPU上同时执行

多线程实现方式

继承Thread类

public class ThreadDemo {
    public static void main(String[] args) {

        MyThread t1 = new MyThread();
        t1.start();
    }

}

public class MyThread extends Thread {

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Hello World");
        }
    }
}

【多线程】 - 实现方法以及自定义线程池_线程池

实现Runnable接口的方式进行实现

public class ThreadDemo02 {
    public static void main(String[] args) {
        Myrun mr = new Myrun();
        Thread t1 = new Thread(mr);
        t1.start();

    }

}
public class Myrun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Hello World");
        }
    }
}

利用Callable接口和Future接口方式实

特点:可以获取到多线程运行结果

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThreadDemo03 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
       //创建MyCallahle对象
        MyCallable mc = new MyCallable();
        FutureTask<Integer> ft = new FutureTask<>(mc);
        Thread t1 = new Thread(ft);
        t1.start();
        Integer result = ft.get();
        System.out.println(result);

    }

}


import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum+=i;
        }
        return sum;
    }
}

多线程三种实现方式对比

【多线程】 - 实现方法以及自定义线程池_java_02

常见的成员方法

设置以及获取线程的优先级

默认优先级为5,优先级从1~10,10最大,优先级越高抢到CPU概率越高

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThreadDemo04 {
    public static void main(String[] args)  {
        MyRunnable mr = new MyRunnable();
        Thread t1 = new Thread(mr,"飞机");
        Thread t2 = new Thread(mr,"坦克");

        System.out.println(t1.getPriority());
        System.out.println(t2.getPriority());

    }

}

【多线程】 - 实现方法以及自定义线程池_线程池_03

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThreadDemo04 {
    public static void main(String[] args)  {
        MyRunnable mr = new MyRunnable();
        Thread t1 = new Thread(mr,"飞机");
        Thread t2 = new Thread(mr,"坦克");
//
//        System.out.println(t1.getPriority());
//        System.out.println(t2.getPriority());
        t1.setPriority(1);
        t2.setPriority(10);
        t1.start();
        t2.start();

//


    }

}

【多线程】 - 实现方法以及自定义线程池_java_04

设置为守护线程

守护进程更通俗的来说就是“备胎”,非守护进程就相当于你的女神,当非守护进程执行完毕之后,守护进程会陆续结束,就好比你追到你女神了,然后官宣了,然后“备胎”看见了,慢慢的慢慢的就对你疏远了

【多线程】 - 实现方法以及自定义线程池_java_05

应用场景:

【多线程】 - 实现方法以及自定义线程池_线程池_06

当聊天界面关闭以后,传输文件就没必要执行了

出让线程

【多线程】 - 实现方法以及自定义线程池_实现方法_07

插入线程

【多线程】 - 实现方法以及自定义线程池_实现方法_08

线程的生命周期

【多线程】 - 实现方法以及自定义线程池_java_09

【多线程】 - 实现方法以及自定义线程池_java_10

JVM里是没有运行状态的,这里只是为了方便理解。

线程安全问题

同步代码块

为了解决线程的随机性,在操作一些共享数据的代码时,会把作共享数据的代码锁起来

特点:锁默认打开,有一个进程进去了,锁自动关闭;里面的代码全部执行完毕,线程出来,锁自动打开

【多线程】 - 实现方法以及自定义线程池_java_11

【多线程】 - 实现方法以及自定义线程池_线程池_12

Lock锁

手动上锁与开锁

【多线程】 - 实现方法以及自定义线程池_线程池_13

线程池

1.创建一个池子,池子中是空的

2.提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还给池子,下回再次提交任务时,不需要创建新的线程,直接复用已有的线程即可

3.但是如果提交任务时,池子中没有空闲线程,也无法创建新的线程,任务就会排队等待

Executors:线程池的工具类通过调用方法返回不同类型的线程池对象。

【多线程】 - 实现方法以及自定义线程池_线程池_14

【多线程】 - 实现方法以及自定义线程池_实现方法_15

自定义线程池

【多线程】 - 实现方法以及自定义线程池_java_16

什么时候才会创造临时线程

当核心线程都在忙而且队伍当中已经排满了任务,这个时候才会创建临时线程

【多线程】 - 实现方法以及自定义线程池_java_17

当线程池满负荷运行时,就是触发任务拒绝策略

【多线程】 - 实现方法以及自定义线程池_实现方法_18

【多线程】 - 实现方法以及自定义线程池_实现方法_19

public class MyThreadPoolDemo {
    public static void main(String[] args) {

        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                3,//核心线程数
                6,//最大线程数
                60,//空闲线程存活时间
                TimeUnit.SECONDS,//单位
                new ArrayBlockingQueue<>(3),//任务队列
                Executors.defaultThreadFactory(),//创建线程工厂
                new ThreadPoolExecutor.AbortPolicy()//任务拒绝策略
        );
    }
}

线程池多大合适

最大并行数

【多线程】 - 实现方法以及自定义线程池_实现方法_20

CPU密集型(项目计算多)

最大并行数+1

I/O密集型(读取文件多)

【多线程】 - 实现方法以及自定义线程池_实现方法_21

【多线程】 - 实现方法以及自定义线程池_实现方法_22

可以用工具thread dump测试时间


举报

相关推荐

0 条评论