线程、多线程、线程池总结

SpringBoot 多线程池实现方案 文章目录一、需求场景二、需要的核心注解三、自定义线程池配置3.1 所需依赖3.2 定义基类 AsyncConstants3.3 定义各线程池配置类PrimaryAsyncConstantsSecondaryAsyncConstants3.4 定义配置文件四、多线程池实现4.1 生成 Executor 对象4.2 声明异步方法4.3 调用示例 一、需求场景 通常情况,在小项目中,业务单一,单个线程池... 阅读详情
 

先看几个概念: 线程:进程中负责程序执行的执行单元。一个进程中至少有一个线程。

多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性。

线程池:基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。

如果对线程概念不清晰的话,不妨先看看我是一个线程这篇文章,拟人化的故事阐述线程的工作原理。

● 线程

创建线程的两种方式:

一、继承Thread类,扩展线程。
class DemoThread extends Thread {

    @Override
    public void run() {
        super.run();
        // Perform time-consuming operation...
    }
}

DemoThread t = new DemoThread();
t.start();
  • 继承Thread类,覆盖run()方法。
  • 创建线程对象并用start()方法启动线程。
面试题
  • 1)线程和进程有什么区别?

一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

  • 2)如何在Java中实现线程?

创建线程有两种方式:
一、继承 Thread 类,扩展线程。
二、实现 Runnable 接口。

  • 3)Thread 类中的 start() 和 run() 方法有什么区别?

调用 start() 方法才会启动新线程;如果直接调用 Thread 的 run() 方法,它的行为就会和普通的方法一样;为了在新的线程中执行我们的代码,必须使用 Thread.start() 方法。

扩展

Android 系统接口 HandlerThread 继承了 Thread,它是一个可以使用 Handler 的 Thread,一个具有消息循环的线程。run()方法中通过 Looper.prepare() 来创建消息队列,通过 Looper.loop() 来开启消息循环。可以在 run() 方法中执行耗时的任务,而 HandlerThread 内部创建了消息队列外界需要通过 Handler 的方式来通知 HandlerThread 执行一个具体任务;HandlerThread 的 run() 方法是一个无限的循环,可以通过它的 quite() 或 quitSafely() 方法来终止线程的执行;

二、实现Runnable接口。
public class DemoActivity extends BaseActivity implements Runnable {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Thread t = new Thread(this);
        t.start();
    }

    @Override
    public void run() {

    }
}
面试题
  • 1)用 Runnable 还是 Thread ?

我们都知道可以通过继承 Thread 类或者调用 Runnable 接口来实现线程,问题是,创建线程哪种方式更好呢?什么情况下使用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口更好了。

  • 2)Runnable 和 Callable 有什么不同?

Runnable 和 Callable 都代表那些要在不同的线程中执行的任务。Runnable 从 JDK1.0 开始就有了,Callable 是在 JDK1.5 增加的。它们的主要区别是 Callable 的 call() 方法可以返回值和抛出异常,而 Runnable 的 run() 方法没有这些功能。Callable 可以返回装载有计算结果的 Future 对象。

⚠注意:这面第二个面试题主要是为了引出下面的扩展,原谅我这样为难人的出场。

扩展

先看一下 Runnable 和 Callable 的源码

public interface Runnable {
    public void run();
}

public interface Callable<V> {
    V call() throws Exception;
}

可以得出:

1)Callable 接口下的方法是 call(),Runnable 接口的方法是 run()。
2)Callable 的任务执行后可返回值,而 Runnable 的任务是不能返回值的。
3)call() 方法可以抛出异常,run()方法不可以的。
4)运行 Callable 任务可以拿到一个 Future 对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过 Future 对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

但是,但是,凡事都有但是嘛...

单独使用 Callable,无法在新线程中(new Thread(Runnable r))使用,Thread 类只支持 Runnable。不过 Callable 可以使用 ExecutorService (又抛出一个概念,这个概念将在下面的线程池中说明)。

上面又提到了 Future,看一下 Future 接口:

public interface Future<V> {

    boolean cancel(boolean mayInterruptIfRunning);

    boolean isCancelled();

    boolean isDone();

    V get() throws InterruptedException, ExecutionException;

    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

Future 定义了5个方法:

1)boolean cancel(boolean mayInterruptIfRunning):试图取消对此任务的执行。如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。当调用 cancel() 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程。此方法返回后,对 isDone() 的后续调用将始终返回 true。如果此方法返回 true,则对 isCancelled() 的后续调用将始终返回 true。
2)boolean isCancelled():如果在任务正常完成前将其取消,则返回 true。
3)boolean isDone():如果任务已完成,则返回 true。 可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true。
4)V get()throws InterruptedException,ExecutionException:如有必要,等待计算完成,然后获取其结果。
5)V get(long timeout,TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException: 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。

看来 Future 接口也不能用在线程中,那怎么用,谁实现了 Future 接口呢?答:FutureTask。

public class FutureTask<V> implements RunnableFuture<V> {
    ...
}

public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}

FutureTask 实现了 Runnable 和 Future,所以兼顾两者优点,既可以在 Thread 中使用,又可以在 ExecutorService 中使用。

看完上面啰哩啰嗦的介绍后,下面我们具体看一下具体使用的示例:

Callable<String> callable = new Callable<String>() {
    @Override
    public String call() throws Exception {
        return "个人博客:sunfusheng.com";
    }
};

FutureTask<String> task = new FutureTask<String>(callable);

Thread t = new Thread(task);
t.start(); // 启动线程
task.cancel(true); // 取消线程

使用 FutureTask 的好处是 FutureTask 是为了弥补 Thread 的不足而设计的,它可以让程序员准确地知道线程什么时候执行完成并获得到线程执行完成后返回的结果。FutureTask 是一种可以取消的异步的计算任务,它的计算是通过 Callable 实现的,它等价于可以携带结果的 Runnable,并且有三个状态:等待、运行和完成。完成包括所有计算以任意的方式结束,包括正常结束、取消和异常。

查看具体操作代码请参考 《个人学习项目DroidStudy》,感谢您的关注。

● 多线程

多线程的概念很好理解就是多条线程同时存在,但要用好多线程确不容易,涉及到多线程间通信,多线程共用一个资源等诸多问题。

使用多线程的优缺点:
优点:
1)适当的提高程序的执行效率(多个线程同时执行)。
2)适当的提高了资源利用率(CPU、内存等)。
缺点:
1)占用一定的内存空间。
2)线程越多CPU的调度开销越大。
3)程序的复杂度会上升。

对于多线程的示例代码感兴趣的可以自己写Demo啦,去运行体会,下面我主要列出一些多线程的技术点。

synchronized

同步块大家都比较熟悉,通过 synchronized 关键字来实现;所有加上 synchronized 的方法和块语句,在多线程访问的时候,同一时刻只能有一个线程能够访问。

wait()、notify()、notifyAll()

这三个方法是 java.lang.Object 的 final native 方法,任何继承 java.lang.Object 的类都有这三个方法。它们是Java语言提供的实现线程间阻塞和控制进程内调度的底层机制,平时我们会很少用到的。

wait():
导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒,该方法只能在同步方法中调用。

notify():
随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态,该方法只能在同步方法或同步块内部调用。

notifyAll():
解除所有那些在该对象上调用wait方法的线程的阻塞状态,同样该方法只能在同步方法或同步块内部调用。

调用这三个方法中任意一个,当前线程必须是锁的持有者,如果不是会抛出一个 IllegalMonitorStateException 异常。

wait() 与 Thread.sleep(long time) 的区别

sleep():在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),该线程不丢失任何监视器的所属权,sleep() 是 Thread 类专属的静态方法,针对一个特定的线程。
wait() 方法使实体所处线程暂停执行,从而使对象进入等待状态,直到被 notify() 方法通知或者 wait() 的等待的时间到。sleep() 方法使持有的线程暂停运行,从而使线程进入休眠状态,直到用 interrupt 方法来打断他的休眠或者 sleep 的休眠的时间到。
wait() 方法进入等待状态时会释放同步锁,而 sleep() 方法不会释放同步锁。所以,当一个线程无限 sleep 时又没有任何人去 interrupt 它的时候,程序就产生大麻烦了,notify() 是用来通知线程,但在 notify() 之前线程是需要获得 lock 的。另个意思就是必须写在 synchronized(lockobj) {...} 之中。wait() 也是这个样子,一个线程需要释放某个 lock,也是在其获得 lock 情况下才能够释放,所以 wait() 也需要放在 synchronized(lockobj) {...} 之中。

volatile 关键字

volatile 是一个特殊的修饰符,只有成员变量才能使用它。在Java并发程序缺少同步类的情况下,多线程对成员变量的操作对其它线程是透明的。volatile 变量可以保证下一个读取操作会在前一个写操作之后发生。线程都会直接从内存中读取该变量并且不缓存它。这就确保了线程读取到的变量是同内存中是一致的。

ThreadLocal 变量

ThreadLocal 是Java里一种特殊的变量。每个线程都有一个 ThreadLocal 就是每个线程都拥有了自己独立的一个变量,竞争条件被彻底消除了。如果为每个线程提供一个自己独有的变量拷贝,将大大提高效率。首先,通过复用减少了代价高昂的对象的创建个数。其次,你在没有使用高代价的同步或者不变性的情况下获得了线程安全。

join() 方法

join() 方法定义在 Thread 类中,所以调用者必须是一个线程,join() 方法主要是让调用该方法的 Thread 完成 run() 方法里面的东西后,再执行 join() 方法后面的代码,看下下面的"意思"代码:

Thread t1 = new Thread(计数线程一);  
Thread t2 = new Thread(计数线程二);  
t1.start();  
t1.join(); // 等待计数线程一执行完成,再执行计数线程二
t2.start();

启动 t1 后,调用了 join() 方法,直到 t1 的计数任务结束,才轮到 t2 启动,然后 t2 才开始计数任务,两个线程是按着严格的顺序来执行的。如果 t2 的执行需要依赖于 t1 中的完整数据的时候,这种方法就可以很好的确保两个线程的同步性。

Thread.yield() 方法

Thread.sleep(long time):线程暂时终止执行(睡眠)一定的时间。
Thread.yield():线程放弃运行,将CPU的控制权让出。

这两个方法都会将当前运行线程的CPU控制权让出来,但 sleep() 方法在指定的睡眠时间内一定不会再得到运行机会,直到它的睡眠时间完成;而 yield() 方法让出控制权后,还有可能马上被系统的调度机制选中来运行,比如,执行yield()方法的线程优先级高于其他的线程,那么这个线程即使执行了 yield() 方法也可能不能起到让出CPU控制权的效果,因为它让出控制权后,进入排队队列,调度机制将从等待运行的线程队列中选出一个等级最高的线程来运行,那么它又(很可能)被选中来运行。

扩展

线程调度策略

(1) 抢占式调度策略

Java运行时系统的线程调度算法是抢占式的。Java运行时系统支持一种简单的固定优先级的调度算法。如果一个优先级比其他任何处于可运行状态的线程都高的线程进入就绪状态,那么运行时系统就会选择该线程运行。新的优先级较高的线程抢占了其他线程。但是Java运行时系统并不抢占同优先级的线程。换句话说,Java运行时系统不是分时的。然而,基于Java Thread类的实现系统可能是支持分时的,因此编写代码时不要依赖分时。当系统中的处于就绪状态的线程都具有相同优先级时,线程调度程序采用一种简单的、非抢占式的轮转的调度顺序。

(2) 时间片轮转调度策略

有些系统的线程调度采用时间片轮转调度策略。这种调度策略是从所有处于就绪状态的线程中选择优先级最高的线程分配一定的CPU时间运行。该时间过后再选择其他线程运行。只有当线程运行结束、放弃(yield)CPU或由于某种原因进入阻塞状态,低优先级的线程才有机会执行。如果有两个优先级相同的线程都在等待CPU,则调度程序以轮转的方式选择运行的线程。

以上把这些技术点总结出来,后面我会把多线程这块的示例代码更新到 《个人学习项目DroidStudy》,感谢您的关注。

● 线程池

创建多个线程不光麻烦而且相对影响系统性能,接下来让我看看使用线程池来操作多线程。我把自己的 《个人学习项目DroidStudy》 中线程池转成一个 gif 效果图,大家可以实际把玩下去感受线程池的原理,有兴趣的同学也可以先 star 下,我会在接下来的几个月把这个学习的Demo工程完善好。


线程池.gif
线程池的优点

1)避免线程的创建和销毁带来的性能开销。
2)避免大量的线程间因互相抢占系统资源导致的阻塞现象。
3}能够对线程进行简单的管理并提供定时执行、间隔执行等功能。

再撸一撸概念

Java里面线程池的顶级接口是 Executor,不过真正的线程池接口是 ExecutorService, ExecutorService 的默认实现是 ThreadPoolExecutor;普通类 Executors 里面调用的就是 ThreadPoolExecutor。

照例看一下各个接口的源码:

public interface Executor {
    void execute(Runnable command);
}

public interface ExecutorService extends Executor {
    void shutdown();
    List<Runnable> shutdownNow();

    boolean isShutdown();
    boolean isTerminated();

    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    ...
}

public class Executors {
    public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, 
                            new SynchronousQueue<Runnable>());
    }
    ...
}

下面我创建的一个线程池:

ExecutorService pool = Executors.newCachedThreadPool();

Executors 提供四种线程池:

  • 1)newCachedThreadPool 是一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute() 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。

  • 2)newSingleThreadExecutor 创建是一个单线程池,也就是该线程池只有一个线程在工作,所有的任务是串行执行的,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它,此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

  • 3)newFixedThreadPool 创建固定大小的线程池,每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小,线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

  • 4)newScheduledThreadPool 创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求。

通过 ThreadPoolExecutor 的构造函数,撸一撸线程池相关参数的概念:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, 
        threadFactory, defaultHandler);
}
  • 1)corePoolSize:线程池的核心线程数,一般情况下不管有没有任务都会一直在线程池中一直存活,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 设置为 true 时,闲置的核心线程会存在超时机制,如果在指定时间没有新任务来时,核心线程也会被终止,而这个时间间隔由第3个属性 keepAliveTime 指定。

  • 2)maximumPoolSize:线程池所能容纳的最大线程数,当活动的线程数达到这个值后,后续的新任务将会被阻塞。

  • 3)keepAliveTime:控制线程闲置时的超时时长,超过则终止该线程。一般情况下用于非核心线程,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 设置为 true时,也作用于核心线程。

  • 4)unit:用于指定 keepAliveTime 参数的时间单位,TimeUnit 是个 enum 枚举类型,常用的有:TimeUnit.HOURS(小时)、TimeUnit.MINUTES(分钟)、TimeUnit.SECONDS(秒) 和 TimeUnit.MILLISECONDS(毫秒)等。

  • 5)workQueue:线程池的任务队列,通过线程池的 execute(Runnable command) 方法会将任务 Runnable 存储在队列中。

  • 6)threadFactory:线程工厂,它是一个接口,用来为线程池创建新线程的。

线程池的关闭

ThreadPoolExecutor 提供了两个方法,用于线程池的关闭,分别是 shutdown() 和 shutdownNow()。

shutdown():不会立即的终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务。
shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务。

面试题

1)什么是 Executor 框架?

Executor框架在Java 5中被引入,Executor 框架是一个根据一组执行策略调用、调度、执行和控制的异步任务的框架。

无限制的创建线程会引起应用程序内存溢出,所以创建一个线程池是个更好的的解决方案,因为可以限制线程的数量并且可以回收再利用这些线程。利用 Executor 框架可以非常方便的创建一个线程池。

2)Executors 类是什么?

Executors为Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类提供了一些工具方法。Executors 可以用于方便的创建线程池。

查看具体操作代码请参考 《个人学习项目DroidStudy》,感谢您的关注。

关于我

个人邮箱:sfsheng0322@126.com
GitHub主页
简书主页
个人博客
新浪微博



作者:孙福生微博
链接:http://www.jianshu.com/p/b8197dd2934c
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Cadence OrCAD常见引脚错误排查指南:从原理图到封装的完整解决方案 本文详细解析Cadence OrCAD设计中常见的引脚错误问题,提供从原理图到封装的系统化解决方案。涵盖错误诊断、元件库修复、封装管理及自动化处理技巧,帮助工程师高效解决ORCAP-36022等典型错误,确保设计流程顺畅。 阅读详情

相关推荐

【Stata双重差分模型】双重差分DID的具体操作步骤

本案例将详细阐述如何使用双重差分法进行实证分析,并展示具体的STATA操作代码。

a519573917的博客 2万+

多线程及线程池

目录 线程 线程池(ThreadPool) 线程池的7大参数 线程池之阻塞队列 线程池之拒绝策略(RejectedExecutionHandler ) 监控线程池的运行状态 部分源码分析 线程 线程是调度CPU资源的最小单位,线程模型分为KLT模型与ULT模型,JVM使用的KLT模型,Java线程与OS线程保持1:1的映射关系,也就是说有一个java线程在操作系统里面也会有一个对应的线程,Java线程有多种声明状态 NEW:新建 RUNNABLE:运行 BOLCKE....

qq_44447372的博客 1512

本地服务器搭建Uptime Kuma网站监控服务

本文主要介绍如何在Linux系统中一键部署Uptime Kuma运维监控服务,并将这个服务映射至公网实现随时随地远程访问。如果您像我一样在服务器上托管了多个网站,并且没有足够的时间来手动检查每个网站的在线状态,那么当出现问题时,您可能无法及时收到通知来处理这些问题。因此,搭建一个在线监控服务是很有必要的,它可以在状态异常时提醒您,以便您能够及时处理问题,确保网站的稳定性和可用性。监控服务有很多,我最终选择了Uptime Kuma,因为Uptime Kuma是开源免费的,

Tiam_cr的博客 1823

线程、多线程以及线程池详解与总结

什么是进程? 进程是程序一次动态执行的过程。一个程序一般是一个进程,也可以有多个进程。一个进程可以有多个线程,但只有一个主线程。进程与程序不是一 一对应的。系统中没有相同的进程(开始时间不同)。 什么是线程? 线程(thread): 是操作系统能够进行运算调度的最小单位。线程是进程的一部分,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。线程是独立调度和分派的基本单位。同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,

qq_47768542的博客 805

从零开始:在CentOS服务器上部署R Shiny应用的完整指南

本文提供了一份在CentOS服务器上部署R Shiny应用的完整实战指南。内容涵盖从创建专用用户、安装R语言环境、配置Shiny Server,到最终部署应用并配置防火墙的全过程。针对部署过程中常见的权限、端口及依赖问题,给出了详细的解决方案,旨在帮助数据分析师和开发者将本地Shiny应用稳定、安全地发布至生产环境。

weixin_29079743的博客 135

Twincat Scopeview录波中的Ringbuffer设置技巧与常见问题解决

本文深入解析了倍福Twincat Scopeview录波功能中Ringbuffer(环形缓冲区)的核心设置技巧与常见问题解决方案。针对数据丢失、触发时机不准等痛点,详细阐述了缓冲区大小、预触发样本、采样率等关键参数的优化配置,并提供了多通道同步、自动诊断等实战应用指南,帮助工程师高效捕捉和分析PLC数据。

rainy的博客 845

线程、多线程与线程池总结

线程、多线程与线程池总结

张无忌_蜘蛛侠的博客 735

让Qt程序适配高分辨率屏幕,解决软件界面错乱异常

前期使用Qt开发一个登录模块一直使用很好。最近在一台新电脑上使用时发现排版混乱。这个问题很普遍,主要原因是旧软件对高清显示器的适配不当造成的。新电脑使用的是4K屏,win10系统自动进行了175%的缩放。

cihron的博客 1万+

多线程+线程池(知识分享)

1.1 多线程的概念多线程是指在一个程序中同时执行多个线程,每个线程都可以独立执行,各自完成自己的任务。多线程的实现可以提高程序的性能和响应速度,尤其是在需要同时执行多个耗时的任务时。在多线程中,不同的线程可以访问相同的内存空间,从而可以共享数据和资源,但也需要注意线程安全的问题。多线程编程需要考虑线程的创建、启动、停止、同步等问题,同时也需要避免线程死锁、饥饿等问题线程池是一种用于管理和重用线程的机制。

CKApril_java的博客 3551

13、混合系统的离散与连续交互

本文详细探讨了混合系统中离散事件与连续动态的交互机制,涵盖了建模方法、分析技术、设计挑战以及多种控制策略。通过具体案例研究和操作语义的定义,展示了混合系统在制造业、交通系统、机器人技术和过程控制等领域的广泛应用。文章还介绍了实验仿真、稳定性研究及优化方法,旨在帮助读者全面理解混合系统的设计与控制要点,并为未来智能化和自适应混合系统的发展提供了展望。

5f4d3s2a1q的博客 127

【PostgreSQL教程】PostgreSQL 高级篇之子查询

子查询也可称为内部查询、嵌套查询,指的是在 PostgreSQL 查询中的 WHERE 子句中嵌入查询语句。一个 SELECT 语句的查询结果能够作为另一个语句的输入值。子查询可以与 SELECT、INSERT、UPDATE 和 DELETE 语句一起使用,并可使用运算符如 =、、>=、

No8g攻城狮的博客 1206

线程池,内存池,连接池,对象池,请求池......

池都是起到一个缓冲的作用,不需要从操作系统中重新申请。不需要每次都创建线程,每次用线程的时候,从线程池里面写出一个,避免创建与销毁。 线程池的应用 Io处理的时候 日志处理的时候 设计到池,有什么设计模式,单例模式 线程池的组成 1.执行队列,线程 2.任务队列,任务 3.管理组件 线程池代码 ...

MrZhuangzhipeng的博客 751

FCTA/FCTB 前方交通穿行预警/制动系统技术规范

FCTA&FCTB前方交叉路口预警制动系统是针对十字路口和停车场等"鬼探头"场景设计的驾驶辅助系统。系统在自车速度0-40km/h范围内工作,通过角雷达和摄像头检测侧向来车.

未知艺术家的博客 743

Linux多线程【线程池】

线程池是一种管理线程的机制,它可以在需要时自动创建和销毁线程,以及分配和回收线程资源。线程池的主要优点是减少了频繁创建和销毁线程所带来的开销,提高了系统的稳定性和可扩展性。此外,线程池还可以有效地控制线程的数量,避免过多线程导致的资源竞争和系统过载

北 海的博客 2541

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

多线程,线程池,线程的创建,线程池的参数

​ 进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位。线程也被称为轻量级进程,线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不拥有系统资源,它与父进程的其它线程共享该进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。

weixin_44797327的博客 1302

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Python 多线程与线程池

Python多线程与线程池是处理I/O密集型任务的高效工具。本文从基础到进阶,详解了多线程的使用方法。首先介绍了线程概念和Python的threading模块,包括线程创建、同步机制(如Lock)等。随后讲解了线程池的优势及ThreadPoolExecutor的使用方法,对比了两种方式的性能和适用场景。文章还分析了GIL对多线程的影响,并提供了规避策略。最后通过网页爬取案例,展示了多线程和线程池的实际应用。对于I/O密集型任务,线程池因其简洁高效更推荐使用;而CPU密集型任务则建议改用多进程处理。

余子越的博客 1779

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

线程池和多线程的区别

线程池的概念 线程池大类总共分为4种 fixThreadPool 正规线程(传统线程池) cacheThreadPool 缓存线程池 singleThreadPoll 单线程线程池(单例线程池) ScheduledThreadPoll 周期性执行任务的线程池 fixThreadPool 正规线程(传统线程池) 含有核心线程,核心线程即为最大线程数量,没有非核心线程 cacheThr...

董皓宇 8779

python 多线程与线程池

简单的多线程—使用线程池 from multiprocessing import Pool def f(x): # 基本函数返回 x的平方 return x * x def my_callback(x): # 回调函数,打印x print(x) def multicore(): pool = Pool(4) # 创建可容纳四个进...

红叶谷 wsp_1138886114的博客 4240

Java多线程、锁、线程池详解

通过本文的介绍,我们深入了解了Java中的多线程、锁机制、线程池的原理和应用。多线程可以提高程序的执行效率,但同时也带来了线程安全的问题。锁机制可以解决线程安全问题,而线程池则可以提高线程的复用率,减少线程创建和销毁的开销。理解这些概念的原理和应用可以帮助开发者编写高效、可靠的并发程序。希望本文能够帮助大家更好地理解和掌握Java中的多线程、锁和线程池,提升编程水平。

weixin_67825126的博客 2136

线程、多线程以及线程池的关系与用法

在没有线程池的情况下,创建线程主要有以下几种方式: 这种方式直接继承 类并重写 方法。 缺点:Java 不支持多继承,如果类已经继承了其他类,则无法再继承 。 (2) 实现 接口 这种方式更灵活,因为一个类可以同时实现多个接口。 需要手动创建 对象并将 实例传递给它。 (3) 实现 接口 接口允许任务返回结果,并可以抛出异常。 需要与 配合使用。 多线程 定义:通过多个线程并发或并行执行任务,实现高效处理。 实现方式: 直接创建多个线程:手动创建和启动多个线程对象。

mjr_l的博客 1217

多线程与线程池

线程是系统能够调度的最小单元,在一个进程里面可以有多个线程,进程中负责程序执行的执行单元。一个进程中至少有一个线程。当多个线程访问某个类时,不管运行时环境采用何种类、调度方式或者这些线程将如何交替执行,并且在主要调用代码中不需要任何额外的同步和协同,这个类能表现出正确的行为,那么这个类就是线程安全的那么怎么保证线程安全嘞就是把对象封闭到一个线程里,只有这一个线程能够看到此对象。那么就算是这个对象不是线程安全的也不会出现不安全的问题,这就是线程封闭。

2302_77971734的博客 1298

java多线程及线程池

多线程是指在一个程序中同时运行多个线程,每个线程都是独立的执行流程,可以在同一时间内执行不同的任务,从而提高程序的并发性和效率。1、等待与睡眠Thread.sleep(long millis):使当前线程进入睡眠状态,直到指定时间过去或被中断。Object.wait():使当前线程等待,直到其他线程调用 notify() 或 notifyAll()。Thread.join():等待指定线程完成执行。2、I/O 操作。

yogima的博客 1097

Java强化:多线程及线程池

指多个线程同时操作同一个共享资源,且对该资源进行修改时,可能出现的业务安全问题。

weixin_63950083的博客 1283

【多线程】多线程案例——线程池详解与实现

多线程案例详解,线程池执行流程,Java标准库的线程池详解,Java中Executors类使用详解,ThreadPoolExecutor 类详解,ThreadPoolExecutor所有参数详解(RejectedExecutionHandler拒绝策略等),模拟实现线程池,多线程总结,保证线程安全的思路,对比进程和线程

ZXT的博客 2270

多线程编程:线程池

线程池作为并发编程的基石技术,其设计需要在 资源效率、响应速度 和 系统稳定性 之间寻找平衡点。在传统多线程编程中,每次任务处理都需要经历 线程创建→任务执行→线程销毁 的完整生命周期。线程池的核心价值:通过 线程复用 和 任务队列缓冲,将系统资源利用率提升30%~70%(根据Intel实验数据)。三、代码深度解析(基于C/pthread实现)一、引言:为什么需要线程池?二、线程池的四大核心组件。五、应用场景与选型建议。四、线程池的进阶特性。

2301_80067496的博客 1406

多线程和线程池的区别

多线程是一种并发执行的技术,它允许在同一进程中同时执行多个线程。每个线程可以执行程序中的一部分代码,从而提高程序的执行效率。资源共享:同一进程中的多个线程共享进程的内存空间和资源,这使得线程之间的通信非常高效。并发性:多个线程可以同时进行,操作系统能够在多个线程之间快速切换,给用户提供并行处理的感觉。轻量级:相对于进程,线程是轻量级的,因为线程的创建和销毁比进程更快,并且线程之间的上下文切换成本较低。应用场景。

m0_63903713的博客 1292
上一篇: 查询某段时间的数据
下一篇: 事务传播行为类型
冷down
博客等级 码龄10年 11粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值