首页 > 其他分享 >线程池

线程池

时间:2024-04-28 11:24:10浏览次数:22  
标签:runnable int void 线程 new public

线程池

1. 线程池概念

 

2. 标准库线程池 (面试考点)

 

总结:

 

 

3. 工厂类创建线程池和基本使用

查看代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Test {
    public static void main(String[] args) {
        // 1. 能够根据任务的数目, 自动进行线程扩容.
        // 可以会创建很多个线程, 系统负担大, 不好
        // ExecutorService service = Executors.newCachedThreadPool();

        // 2. 固定创建10个线程的线程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10000; i++) {
            int id = i;
            // 往线程池里添加任务
            service.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello " + id + ", " + Thread.currentThread().getName());
                }
            });
        }
    }
}

 

 

4. 自己实现线程池

查看代码
 import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class MyThreadPool {

    // 阻塞队列
    private  BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);

    // 初始化 创建固定线程的线程池 (FixedThreadPool)
    public MyThreadPool(int n) {
        for (int i = 0;i < n;i++) {
            Thread t = new Thread( () -> {
                try {
                    while (true) {
                        Runnable runnable = queue.take();
                        runnable.run();
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            t.start();
        }
    }

    // 把任务添加到线程池中
    public void submit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }

}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPool threadPool = new MyThreadPool(10);
        for (int i = 0;i < 10000;i++) {
            // 往线程池里添加任务
            int id = i;
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello " + id + ", " + Thread.currentThread().getName());
                }
            });
        }
    }
}

 

关于核心线程, 最大线程数的调整

查看代码
 

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

// 写一个比较简单的线程池.
class MyThreadPool {
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);
    private int maxPoolSize = 0;
    private List<Thread> threadList = new ArrayList<>();

    // 初始化线程池 (FixedThreadPool)
    public MyThreadPool(int corePoolSize, int maxPoolSize) {
        this.maxPoolSize = maxPoolSize;
        // 创建若干个线程
        for (int i = 0; i < corePoolSize; i++) {
            Thread t = new Thread(() -> {
                try {
                    while (true) {
                        Runnable runnable = queue.take();
                        runnable.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            t.start();
            threadList.add(t);
        }
    }

    // 把任务添加到线程池中
    void submit(Runnable runnable) throws InterruptedException {
        // 此处进行判定, 判定说当前任务队列的元素个数, 是否比较长.
        // 如果队列元素比较长, 说明已有的线程, 不太能处理过来了. 创建新的线程即可.
        // 如果队列不是很长, 没必要创建新的线程.
        queue.put(runnable);

        // 这里的 阈值 都是咱们拍脑门想的.
        while (queue.size() >= 500 && threadList.size() < maxPoolSize) {
            // 创建新的线程即可
            Thread t = new Thread(() -> {
                try {
                    while (true) {
                        Runnable task = queue.take();
                        task.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            t.start();
            threadList.add(t);
        }
    }
}

class Demo35 {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPool threadPool = new MyThreadPool(10, 20);

        for (int i = 0; i < 10000; i++) {
            int id = i;
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello " + id + ", " + Thread.currentThread().getName());
                }
            });
        }
    }
}

 

5. 定时器

库函数实现:

查看代码
import java.util.Timer;
import java.util.TimerTask;

class Demo36 {
    public static void main(String[] args) {
        Timer timer = new Timer();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello 3000");
            }
        }, 3000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello 2000");
            }
        }, 2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello 1000");
            }
        }, 1000);
    }
}

 

自己实现:

查看代码
 import java.util.Comparator;
import java.util.PriorityQueue;

class MyTimerTask implements Comparator<MyTimerTask>,Comparable<MyTimerTask> {
    private Runnable runnable;

    private long time;

    public MyTimerTask(Runnable runnable, long delay) {
        this.runnable = runnable;
        this.time += System.currentTimeMillis() + delay;
    }

    public void run() {
        this.runnable.run();
    }

    public long getTime() {
        return this.time;
    }

    @Override
    public int compare(MyTimerTask o1, MyTimerTask o2) {
        return (int) (o1.time - o2.time);
    }

    @Override
    public int compareTo(MyTimerTask o) {
        return (int) (this.time - o.time);
    }
}

class MyTimer {

    // 得是小跟堆, 谁总时间小,谁优先级高
    private PriorityQueue<MyTimerTask> heap = new PriorityQueue<>();

    private Object locker = new Object();

    // 添加任务进小根堆
    public void schedule(Runnable runnable,long delay) {
        synchronized (locker) {
            MyTimerTask myTimerTask = new MyTimerTask(runnable,delay);
            heap.offer(myTimerTask);
            locker.notify();
        }
    }

    public MyTimer() {
        Thread t = new Thread( () -> {
            try {
                synchronized (locker) {
                    while (true) {
                        if (heap.isEmpty()) {
                            locker.wait();
                        }
                        MyTimerTask top = heap.peek();
                        long curTime = System.currentTimeMillis();
                        if (top.getTime() <= curTime) {
                            // 任务可以执行了
                            top.run();
                            heap.poll();
                        }else {
                            // 任务制定时间 - 当前时间 = 需要等待的时间
                            locker.wait(top.getTime() - curTime);
                        }
                    }
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.start();
    }
}



class Test {
    public static void main(String[] args) {
        MyTimer timer = new MyTimer();

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 3000");
            }
        }, 3000);

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2000");
            }
        }, 2000);

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1000");
            }
        }, 1000);

    }
}

标签:runnable,int,void,线程,new,public
From: https://www.cnblogs.com/xumu7/p/18156975

相关文章

  • 不推荐把“线程”注入到Spring、在线程中使用Spring的Bean的方法
    一、不推荐把“线程”注入到spring将线程注入到Spring容器中并不是一个常见的做法,而且通常也不推荐这样做,原因如下:生命周期管理困难:Spring管理的Bean生命周期由Spring容器管理,而线程的生命周期由JVM管理。将线程注入到Spring容器中会导致线程的生命周期与Spring容器的生命周......
  • [Java]线程生命周期与线程通信
    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)https://www.cnblogs.com/cnb-yuchen/p/18162522出自【进步*于辰的博客】线程生命周期与进程有诸多相似,所以我们很容易将两者关联理解并混淆,一些细节之处确有许多不同,因为线程调度与进程调度虽都由CPU完成,但两者并......
  • 进程和线程
    线程和进程linux中,进程和线程都用task_struct结构体表示,只是进程和线程的区别在于task_struct中的mm和files等资源是否共享。记录层面task_struct中有两个字段记录的是编号pid_tpid;/*processid*/task编号,唯一标识一个taskpid_ttgid;/*threadgroupid*/线程组编......
  • Java 多线程初步总结
    Java多线程程序,进程,线程的基本概念:程序:是为了完成特定的任务,使用某种语言编写的一组指令的集合,是一段静态的代码,静态对象,如Excel,World等。进程:是程序的一次执行多次,或者是正在运行的一个程序,是一个动态的过程,有自身的产生,存在和消亡的过程,即存在生命周期。线程:进程可以进一步......
  • openharmony 多线程的方式有哪些?两个worker线程数据如何通讯、内存如何共享、与Java多
    OpenHarmony操作系统支持多种多线程并发处理策略,以提升应用的响应速度与帧率,以及防止耗时任务对主线程的干扰。以下是OpenHarmony中的多线程方式,以及Worker线程间的数据通讯和内存共享方法,还有它们与Java多线程的区别:OpenHarmony多线程方式Worker线程:OpenHarmony中的Worker是......
  • gdb 根据c语言二进制文件进程号查看内部多线程任务
    C语言二进制文件a编译时添加了-g(gdb调试),但是gdba这种方式有时不容易复现一些场景。这时可以先正常启动a,然后根据a的进程号启动gdb调试。#1.找到程序进程号psaux|grepa#2.使用GDB附加到该进程sudogdb-p[PID]#3.使用infothreads命令来列出......
  • 进程线程基础知识
    进程线程基础知识pcb包含的具体信息进程描述信息(进程标识符,用户标识符)进程管理状态(进程当前的状态,进程的优先级)资源分配清单cpu信息pcb通过链表的方式来进行组织,把具有相同状态的进程链在一起组成队列。进程的上下文切换一个进程切换到另一个进程运行,称为进程的上下文切......
  • Java面试题:SimpleDateFormat是线程安全的吗?使用时应该注意什么?
    在日常开发中,我们经常会用到时间,我们有很多办法在Java代码中获取时间。但是不同的方法获取到的时间的格式都不尽相同,这时候就需要一种格式化工具,把时间显示成我们需要的格式。最常用的方法就是使用SimpleDateFormat类。这是一个看上去功能比较简单的类,但是,一旦使用不当也有可能导......
  • python多线程
    多线程的原理是在同一进程内创建多个线程来执行不同的任务,这些线程共享同一进程的资源,包括内存空间、文件句柄等。每个线程拥有独立的执行路径,可以并行执行任务,从而提高程序的效率。在代码中,通过调用threading.Thread类创建了多个线程对象。每个线程对象都有一个target参数......
  • 【python】pyqt中使用多线程处理耗时任务
    在PyQt中使用多线程通常是为了避免界面冻结,特别是在执行耗时的任务时。PyQt本身是基于Qt的,而Qt不允许在除主线程之外的线程中直接操作GUI元素。因此,任何涉及GUI更新的操作都应该在主线程中执行。importsysimportthreadingfromPyQt5.QtWidgetsimportQApplic......