多线程编程的精华:探索 Java 中的多种线程开启方式
继承Thread,重写run方法
/**
* desc:集成Thread类,重写run方法,调用start方法
* created by cuiyongxu on 2021/12/15 12:33 上午
*/
public class ThreadTask {public static void main(String[] args) {System.out.println(ThreadTask.class.getName() + "-" + Thread.currentThread().getId());ThreadItem threadItem = new ThreadItem();threadItem.start();}
}
class ThreadItem extends Thread {@Overridepublic void run() {System.out.println(this.getClass().getName() + "-" + Thread.currentThread().getId());}
}//执行结果:
//ThreadTask-1
//ThreadItem-10//如果将threadItem.start()换做为thradItem.run() 执行结果为
//ThreadTask-1
//ThreadItem-1
JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))JavaThread *native_thread = NULL;// We cannot hold the Threads_lock when we throw an exception,// due to rank ordering issues. Example: we might need to grab the// Heap_lock while we construct the exception.bool throw_illegal_thread_state = false;// We must release the Threads_lock before we can post a jvmti event// in Thread::start.{// Ensure that the C++ Thread and OSThread structures aren't freed before// we operate.MutexLocker mu(Threads_lock);// Since JDK 5 the java.lang.Thread threadStatus is used to prevent// re-starting an already started thread, so we should usually find// that the JavaThread is null. However for a JNI attached thread// there is a small window between the Thread object being created// (with its JavaThread set) and the update to its threadStatus, so we// have to check for thisif (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {throw_illegal_thread_state = true;} else {// We could also check the stillborn flag to see if this thread was already stopped, but// for historical reasons we let the thread detect that itself when it starts runningjlong size =java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));// Allocate the C++ Thread structure and create the native thread. The// stack size retrieved from java is 64-bit signed, but the constructor takes// size_t (an unsigned type), which may be 32 or 64-bit depending on the platform.// - Avoid truncating on 32-bit platforms if size is greater than UINT_MAX.// - Avoid passing negative values which would result in really large stacks.NOT_LP64(if (size > SIZE_MAX) size = SIZE_MAX;)size_t sz = size > 0 ? (size_t) size : 0;// 看我中文是不是特别醒目 注意thread_entry的使用,看后面的代码片段native_thread = new JavaThread(&thread_entry, sz);// At this point it may be possible that no osthread was created for the// JavaThread due to lack of memory. Check for this situation and throw// an exception if necessary. Eventually we may want to change this so// that we only grab the lock if the thread was created successfully -// then we can also do this check and throw the exception in the// JavaThread constructor.if (native_thread->osthread() != NULL) {// Note: the current thread is not being used within "prepare".native_thread->prepare(jthread);}}}if (throw_illegal_thread_state) {THROW(vmSymbols::java_lang_IllegalThreadStateException());}assert(native_thread != NULL, "Starting null thread?");if (native_thread->osthread() == NULL) {ResourceMark rm(thread);log_warning(os, thread)("Failed to start the native thread for java.lang.Thread \"%s\"",JavaThread::name_for(JNIHandles::resolve_non_null(jthread)));// No one should hold a reference to the 'native_thread'.native_thread->smr_delete();if (JvmtiExport::should_post_resource_exhausted()) {JvmtiExport::post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,os::native_thread_creation_failed_msg());}THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),os::native_thread_creation_failed_msg());}#if INCLUDE_JFRif (Jfr::is_recording() && EventThreadStart::is_enabled() &&EventThreadStart::is_stacktrace_enabled()) {JfrThreadLocal* tl = native_thread->jfr_thread_local();// skip Thread.start() and Thread.start0()tl->set_cached_stack_trace_id(JfrStackTraceRepository::record(thread, 2));}
#endifThread::start(native_thread);JVM_END
static void thread_entry(JavaThread* thread, TRAPS) {HandleMark hm(THREAD);Handle obj(THREAD, thread->threadObj());JavaValue result(T_VOID);JavaCalls::call_virtual(&result,obj,vmClasses::Thread_klass(),vmSymbols::run_method_name(),vmSymbols::void_method_signature(),THREAD);
}
实现Runnable接口,实现run()方法
/**
* desc:
* created by cuiyongxu on 2021/12/15 12:34 上午
*/
public class RunnableTask {public static void main(String[] args) {System.out.println(RunnableTask.class.getName() + "-" + Thread.currentThread().getId());new Thread(new RunnableItem()).start();}
}class RunnableItem implements Runnable {@Overridepublic void run() {System.out.println(this.getClass().getName() + "-" + Thread.currentThread().getId());}
}//输出结果为:
//RunnableTask-1
//RunnableItem-10
实现Callable接口,实现call方法
import com.google.common.collect.Lists;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
/**
* desc:
* created by cuiyongxu on 2021/12/15 12:36 上午
*/
public class CallableTask {public static void main(String[] args) throws Exception {System.out.println(CallableTask.class.getName() + "-" + Thread.currentThread().getId());FutureTask<List<String>> listFutureTask = new FutureTask<>(new CallableItem());Thread thread = new Thread(listFutureTask);thread.start();System.out.println(listFutureTask.get());}
}
class CallableItem implements Callable<List<String>> {@Overridepublic List<String> call() throws Exception {String msg = this.getClass().getName() + "-" + Thread.currentThread().getId();return Lists.newArrayList(msg);}
}
//返回结果为:
//CallableTask-1
//[CallableItem-10]
Executors.newCachedThreadPool
@Test
public void cachedThreadPool() {ExecutorService executorService = Executors.newCachedThreadPool();for (int i = 0; i < 10000; i++) {executorService.submit(() -> {try {Thread.sleep(1000 * 5);System.out.println(Thread.currentThread().getId());} catch (InterruptedException e) {e.printStackTrace();}});}executorService.shutdown();
}
Executors.newFixedThreadPool(2)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/**
* desc:
* created by cuiyongxu on 2021/12/16 10:45 下午
*/
public class NewFixedThreadPoolTask {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(2);long startTime = System.currentTimeMillis();for (int i = 0; i < 10; i++) {int finalI = i;executorService.submit(() -> {System.out.println(finalI+"|"+(System.currentTimeMillis()-startTime));try {Thread.sleep(2000);} catch (InterruptedException e) {}});}executorService.shutdown();}
}/*
0|113
1|113
2|2119
3|2119
4|4120
5|4120
6|6121
7|6121
8|8125
9|8125*/
以上实例中设置最大线程数为2,在执行过程中,每个线程堵塞2s,stateTime只有第一次会初始化,故没两个相邻的线程打印出的耗时是完全相同的,以此证明,在同一时间内,最多只有两个线程可用.输出结果如下:
Executors.newScheduledThreadPool(2)
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/**
* desc:
* created by cuiyongxu on 2021/12/16 11:41 下午
*/
public class NewScheduledThreadPoolTask {public static void main(String[] args) {ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);long startTime = System.currentTimeMillis();for (int i = 0; i < 10; i++) {int finalI = i;executorService.schedule(() ->System.out.println(finalI + "|" + (System.currentTimeMillis() - startTime)), 3, TimeUnit.SECONDS);}executorService.shutdown();}
}
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/**
* desc:
* created by cuiyongxu on 2021/12/16 11:41 下午
*/
public class NewScheduledThreadPoolTask {public static void main(String[] args) {ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);long startTime = System.currentTimeMillis();for (int i = 0; i < 10; i++) {int finalI = i;executorService.scheduleAtFixedRate(() ->System.out.println(finalI + "|" + (System.currentTimeMillis() - startTime)), 0, 3, TimeUnit.SECONDS);}}
}
Executors.newSingleThreadExecutor()
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/**
* @Description :
* @Author : cuiyongxu
* @Date : 2021/12/19-12:58 上午
**/
public class NewSingleThreadExecutorTask {public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {int finalI = i;executorService.execute(() -> {try {System.out.println(finalI);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});}}
}
/*
输出结果为:
0
1
2
3
4
5
6
7
8
9
*/
Executors.newWorkStealingPool()
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/**
* @Description :
* @Author : cuiyongxu
* @Date : 2021/12/19-12:58 上午
**/
public class NewSingleThreadExecutorTask {public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {int finalI = i;executorService.execute(() -> {try {System.out.println(finalI);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});}}
}/*
执行结果:
0
2
1
3
4
5
8
9
6
7
*/
期待您的关注,欢迎访问我的博客
多线程编程的精华:探索 Java 中的多种线程开启方式相关推荐
- java 中的多种判空方式
前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^. 而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!! java 中的多种判空方式 1 ...
- 探索 Java 中的 Date, Calendar, TimeZone 和Timestamp
探索 Java 中的 Date, Calendar, TimeZone 和Timestamp java 2010-12-31 08:56:49 阅读8 评论0 字号:大中小 订阅 对象 宋晟 (sh ...
- 《Java并发编程的艺术》——Java中的并发工具类、线程池、Execute框架(笔记)
文章目录 八.Java中的并发工具类 8.1 等待多线程完成的CountDownLatch 8.2 同步屏障CyclicBarrier 8.2.1 CyclicBarrier简介 8.2.2 Cycl ...
- 12月18日云栖精选夜读 | Java 中创建对象的 5 种方式!...
作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如Spring去创建对象.然而这里有很多创建对象的方法,我们会在这篇文章中学到. Java中有5种创建对象的方式,下面给出它们的 ...
- Java中创建对象的几种方式
Java中创建对象的几种方式 1.使用new创建对象,在堆上创建. 2.克隆 3.反序列化 4.反射创建对象 5.NIO中可以使用本地方法直接分配堆外内存. 转载于:https://www.cnblo ...
- Java中反射的三种常用方式
Java中反射的三种常用方式 package com.xiaohao.test; public class Test{ public static void main(String[] args) t ...
- java中的后台线程、前台线程、守护线程区别
java中的后台线程.前台线程.守护线程区别 区别和联系 区别 联系 区别和联系 区别 后台线程和守护线程是一样的. 后台线程不会阻止进程的终止,而前台线程会, 可以在任何时候将前台线程修改为后台线程 ...
- Java中创建对象的四种方式
为什么80%的码农都做不了架构师?>>> Java中创建对象的四种方式 (1) 用new语句创建对象,这是最常见的创建对象的方法. (2) 运用反射手段,调用java.l ...
- Java中如何实现线程的超时中断
转载自 Java中如何实现线程的超时中断 背景 之前在实现熔断降级组件的时候,需要实现接口请求的超时中断.意思是,业务在使用熔断降级功能时,在平台上设置了一个超时时间,如果请求进入熔断器开始计时,接 ...
最新文章
- python subprocess库 终端命令行命令
- 从寻找可敬的人类开始,扩展未来人类生存的8个维度
- 哥哥,请原谅妹妹的自私!妹妹想做你的新娘...超级感人
- Microsoft Visual Studio International Pack
- 编程题:编写一个函数string_copy()完成strcpy()的作用,并验证。
- java+web+415_使用json返回HTTP状态415的Web服务 - 不支持的媒体类型
- java中elapseTime设置新时间,Java ApplicationLike.getApplicationStartElapsedTime方法代码示例...
- symantec:硝基***针对化工厂商
- JSinput上传图片文件转base64
- vrep外部控制器力矩控制实例——以matlab脚本控制平面两连杆为例
- MatLab 中计算开根号
- Ubuntu下安装Master PDF Editor
- python考试报名官网安徽_2019年3月安徽宿州学院全国计算机等级考试报名通知
- VUE项目引入公共样式的styl文件
- 常吃大蒜对人有什么好处与坏处?
- 3d可视化产品爆炸图案例
- java获取系统dpi_Java DPI介绍
- 数据在链路层传播相关时间计算
- 如何从视频中提取音频?
- 连夜干出来一个自动处理【支付宝交易支付投诉管理系统】,支持多商户
热门文章
- UnicodeEncodeError: ‘gbk‘ codec can‘t encode character ‘\u0467‘ in position 0: illegal multibyte解决方案
- Android自定义View实现图片放大,平移和显示大图片
- 村田 IMU SCC2000系列芯片驱动
- 必看-做好自动化测试的7大技能
- Moto XT882 android2.3 媒体服务器 莫名耗电的原因
- 【Sparkstreaming_01】
- 机你太美 | 华为vs三星折叠屏大战,结果王自如赢了?!
- 基于卷积神经网络(CNN)的中文垃圾邮件检测
- 天馈线测试仪都有什么功能和特点 推荐哪个品牌
- jetbrain家的fleet(已获得预览权限)直接对标vscode , fleet有望超过vscode吗?今天我们实际操作下