Java多线程实现的四种方式

Java多线程的实现有四种方式:1、继承Thread类,重写run方法。
2.通过实现Runnable接口并使用实现类的实例作为Thread构造函数的目标来重写run方法。
3.通过Callable和FutureTask创建线程。
4.使用线程池创建线程。
前两种方法属于不返回类别。
这是因为run方法的返回类型为void,不支持返回结果。
后两个方法属于有返回值类,其返回类型为Object,可以封装结果。
继承Thread类的实现会在执行结果中显示线程名称和自定义信息。
实现Runnable接口的方式是使用该接口实现类的实例作为Thread构造函数参数来启动一个线程,结果显示主进程和线程信息。
使用Callable和FutureTask创建线程。
这涉及到创建一个Callable实现类,使用FutureTask来包装Callable对象和call方法的返回值,最后通过调用FutureTask对象的get方法来检索返回值。
通过线程池创建线程的执行结果会显示该线程池创建的多个线程名称。
通过结合Callable和FutureTask,可以实现Java中线程返回值的功能。
这与前面两种分类描述是一致的。
执行Callable任务后,通过Future对象的get方法检索返回的对象。
get方法是阻塞的,因此程序会一直等待,直到没有结果返回。
Executors类提供了用于创建线程池的工厂方法。
返回的线程池实现了ExecutorService接口。
例如,newFixedThreadPool创建固定数量的线程,newCachedThreadPool创建可缓存的线程池,newSingleThreadExecutor创建单个线程。
newScheduledThreadPool创建一个线程池,支持计划任务定时和线程池。
ExecutorService的submit方法可以调用get方法,该方法传递Callable或Runnable,返回Future对象,并阻塞直到计算完成。
Java架构学习群855801563涵盖Java包括高可用、高并发、高性能、分布式、JVM性能调优、Spring源码、MyBatis、Netty、Redis、Kafka、MySQL、Zookeeper、Tomcat、Docker、Dubbo、Nginx等提供建筑学学习材料。
等知识点适合工作1-5年的Java工程师学习和提高。

java四种线程池创建

探究Java线程池的四个秘密。
创建线程池有四种主要方式,每种方式都有其独特的应用场景和特点。

它在管理并发活动和资源分配方面发挥着关键作用。
您可以通过指定nThreads等corePoolSize参数来精确设置核心线程数。
工作队列使用LinkedBlockingQueue。
当工作超过主线程的处理能力时,最大池大小改为0,表示不限制,但可以通过自定义竞争工厂和处理程序来处理拒绝策略。

2它只有一个核心线程,并且corePoolSize和最大池大小都设置为1,以保证任务按照交付顺序一次执行一个。
当作业太多时,作业队列还使用LinkedBlockingQueue将拒绝的指令抛出RejectedExecutionException。
3.灵活适应性强的短期工作者-newCachedThreadPool

对于需要运行大量异步任务的短期场景,newCachedThreadPool是一个高效的解决方案。
它以0作为corePoolSize并自动调整线程数,直到达到最大池大小(默认整数.MAX_VALUE)。
线程存活时间超过keepAliveTime(默认60秒)后将被重用。
工作队列使用SynchronousQueue来减少线程阻塞。

计划任务和周期性任务的守护者-newScheduledThreadPool

最后,newScheduledThreadPool用于处理需要定期或周期性运行的任务。
它有固定数量的核心线程,并使用DelayedWorkQueue作为任务队列。
您可以在构造方法中设置corePoolSize、最大池大小、KeepAliveTime、unit等参数,并在线程工厂和处理程序中自定义线程和拒绝策略。
DelayedWorkQueue继承自BlockingQueue,提供了put、poll等方法,而Delayed接口则为延迟任务的执行提供了时间约束。

通过了解并灵活使用这些线程池,可以更好地组织和管理Java并发任务,实现更高效的编程。

Java的并行世界-3.0线程池与拒绝策略

Jdk并发相关的核心类:java.util.concurrentjava.util.concurrent.Executors提供了几个静态工厂方法来创建不同类型的线程池,例如:ExecutorServicefixedThreadPool=Executors.newFixedThreadPool(5);ExecutorServicecachedCeachcuolPoolw);执行orServicesingleThreadExecutor=Executors.newSingleThreadExecutor();ScheduledExecutorServicescheduledThreadPool=Executors.newScheduledThreadPool(10);可以通过newThreadPoolExecutor(requires)核数方法手动创建线程池,该方法是传递线程核数的方法,线程停留活。
其中,核心线程数和最大线程数为必填参数,生存时间和任务队列为可选参数。
Java中有四种创建Executor的方法,包括使用newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor和newScheduledThreadPool。
使用该方法时,您可以根据自己的实际需要选择最合适的方式来创建线程池。
无论哪种方式,线程池都可以有效地管理和控制线程,提高程序执行效率。
新的FixedThreadPool创建一个固定大小的线程池。
下面是Java中创建newFixedThreadPool的代码示例:newCachedThreadPool创建一个根据需要自动增长的线程池,并且根据任务数量动态调整线程数量。
下面是newCachedThreadPoolJava代码的示例:新的SingleThreadExecutor创建一个只有一个线程的线程池。
新的ScheduledThreadPool创建了一个支持计划任务的线程池。
ForkJoinPool是一个用于执行分而治之任务的线程池,特别适合递归分解问题,例如并行连接排序、并行求和等。
ForkJoinPoolforkJoinPool=newForkJoinPool();ForkJoinPool位于java.util.concurrent包下,从Java7开始引入,专门用于处理需要递归分解的任务。
它使用工作窃取算法来实现高效的任务调度和线程利用,并且可以充分利用多核处理器。
ForkJoinPool的主要功能包括:下面是一个使用ForkJoinPool计算斐波那契数列值的简单示例:虽然上述五种线程池看似功能特点不同,但内部执行原理都是调用JDK的ThreadPoolExecutor线程池。
好心肠ThreadPoolExecutor构造函数有多个参数,允许根据实际需要配置线程池行为,主要包括:corePoolSize:线程池中的核心线程数,即线程池中维护的最小线程数。
即使线程空闲,核心线程也不会被销毁。
MaximumPoolSize:线程池的最大线程数,即线程池允许的最大线程数。
当任务数量超过核心线程数时,线程池会根据实际情况动态创建新线程,但不会超过最大线程数。
keepAliveTime:非核心线程的空闲时间超过这个时间后,就会被销毁,以控制线程池的大小。
可以通过指定TimeUnit来定义时间单位。
workQueue:任务队列,用于存储等待执行的任务。
ThreadPoolExecutor支持各种类型的任务队列,如ArrayBlockingQueue、LinkedBlockingQueue等。
threadFactory:用于创建线程的工厂,您可以自定义线程的创建方式。
运算符:拒绝策略当线程池和队列已满,无法接受新任务时,拒绝策略将触发以处理新任务。
常见的拒绝策略包括AbortPolicy(默认策略,直接抛出异常)、CallerRunsPolicy(执行被拒绝任务的调用顺序)、DiscardPolicy(丢弃被拒绝的任务)和DiscardOldestPolicy(丢弃队列中最旧的任务)。
ThreadPoolExecutor提供了submit()、execute()等方法来向线程池提交任务。
submit()方法可以接受Callable和Executable类型的任务,并返回一个Future对象,通过该对象可以获取任务执行的结果或者。
取消任务。
execute()方法只能接受Runnable类型的任务,无法获取任务的返回结果。
ThreadPoolExecutor还提供了几种方法来管理和监控线程池状态,例如getActiveCount()、getCompletedTaskCount()、getTaskCount()等。
workQueue:任务队列,已提交但尚未执行的任务。
它的类型是:BlockingQueue接口,只能用来存储Executable对象。
可以通过ArrayBlockingQueue实现排队,当有新任务到来时,如果线程池中实际线程数小于corePoolSize,则先创建一个新线程,如果大于corePoolSize,则将新任务添加到等待队列中;如果队列已满,无法添加,则创建新线程执行任务,前提是线程总数不大于maximumPoolSize,如果大于maximumPoolSize,则拒绝策略;实施的。
无限队列可以通过LinkedBlockingQueue实现与有限队列相比,除非系统资源耗尽,否则当有新任务到达且线程数小于corePoolSize时,线程池会创建新线程来执行该任务。
但是当线程数大于corePoolSize时,创建将不会继续。
如果还有任务传入,系统CPU不是很忙并且还有线程资源,任务就会继续进入队列等待。
优先级任务队列可以通过PriorityBlockingQueue来实现,它可以根据任务的优先级执行任务。
这是一个特殊的、无限的队列。
无限队列和队列需要进行demo测试。
新的CachedThreadPool内部使用了一个SynchronousQueue队列,这是一个实时提交队列系统会添加一个新的线程来执行任务当任务执行完成后,如果启用了大量任务提交,则会回收该线程任务将执行缓慢,系统将启用相同数量的线程处理,直到系统资源耗尽。
ThreadPoolExecutor的核心调度代码包括workerCountOf(c)用于获取当前工作线程池总数,addWorker(command)用于提交任务或创建线程池,reject(command)用于实现拒绝策略。
Handlers是RejectedExecutionHandler接口类型,代表不同的拒绝策略。
常见的拒绝策略包括:CallerRunsPolicy:如果线程池没有关闭,无法放入等待队列的任务将直接在调用者当前线程上执行。
AbortPolicy:会直接抛出异常,阻止系统正常运行。
DiscardPolicy:直接丢弃无法放入等待队列的任务,不抛出异常。
DiscardOldestPolicy:丢弃最旧的请求,然后尝试将当前请求任务添加到等待队列中。
注意:创建ThreadPoolExecutor时需要指定拒绝策略,如果无法满足上述拒绝策略,可以继承RejectedExecutionHandler接口实施自定义拒绝政策。
最常见的用途是升级DiscardPolicy策略,但在放弃之前需要记录请求,示例如下:这里是RejectedExecutionHandler接口的代码,可以重新实现以满足自定义需求。
熟悉了拒绝策略后,线程池中还有一个重要的参数ThreadFactory,它是用来控制线程的创建的。
通过ThreadFactory,您可以实现以下功能:命名线程:通过给线程赋予有意义的名称,可以更轻松地跟踪日志和调试信息。
设置线程属性:设置线程优先级、守护进程状态、异常处理程序等。
根据需要。
自定义线程创建逻辑:添加创建线程的自定义逻辑,如记录线程创建数量、设置线程组等。
这是一个简单的ThreadFactory示例:

java四种线程池创建

Java提供了多种线程池方法来适应不同的并发需求。
首先,newFixedThreadPool创建一个固定大小的核心线程池,适合控制并发数量和排队等待执行的新任务。
其次,newSingleThreadExecutor保证任务是顺序执行的,适合需要按照任务提交顺序处理任务的情况。

为了执行大量短暂的异步任务,newCachedThreadPool是一个自动调整大小的线程池,线程数量根据任务需求动态增加或减少。
此外,newScheduledThreadPool支持计划任务和重复任务。
核心线程是固定的,可以处理ScheduledTasks,比如定时执行或者周期性执行。

但是,DelayedWorkQueue并不是一个线程池,而是Java并发包中的一个接口,用于表示支持延迟元素的工作队列。
DelayedQueue是它的实现之一,比如DelayedWorkQueue接口中的getDelay方法,用于处理时间受限的任务,比如调度定时任务。

总的来说,Java的线程池类型非常丰富多样。
开发者可以根据任务特性选择最合适的线程池,以优化并发性能和资源管理。