Java多线程学习的关键要点和常见案例总结

文章目录

      • Java多线程学习的关键要点:
      • 案例示例:
    • Java多线程编程还包括更多的高级特性和实用技巧
      • 高级主题:
      • 实用案例:
      • 线程池的高级用法和配置:
      • 线程安全的最佳实践:

Java多线程学习的关键要点和常见案例总结如下:

Java多线程学习的关键要点:

  1. 线程基础概念

    • 线程(Thread)是Java程序中执行的最小单位,可以在单个进程中并发执行多个线程。
    • 线程的生命周期包括:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked/Waiting/Timed Waiting)、死亡(Terminated)等状态。
  2. 线程创建

    • 继承Thread类,重写run()方法创建线程。
    • 实现Runnable接口,将其实例传递给Thread构造函数创建线程。
    • 使用Callable接口配合FutureTaskThread创建线程,可以获取线程的返回值。
  3. 线程调度与优先级

    • Java线程有优先级设置,高优先级的线程更有可能先被执行,但这不是绝对保证,由JVM自行调度决定。
  4. 线程同步

    • synchronized关键字用于实现互斥,防止数据竞争,保护共享资源的安全访问。
    • 使用Lock接口和ReentrantLock等实现显式锁,提供了比synchronized更灵活的锁定策略。
  5. 线程间的通信与协作

    • wait(), notify()notifyAll() 方法用于线程间同步和通信。
    • CountDownLatch, Semaphore, CyclicBarrier, Exchanger 等并发工具类提供更强大的线程协作机制。
  6. 线程安全与并发容器

    • 需要保证线程安全时,可以使用Collections.synchronizedXxx()包装类或者java.util.concurrent包下的并发容器,如ConcurrentHashMapCopyOnWriteArrayList等。
  7. 线程池

    • 使用ExecutorServiceThreadPoolExecutor实现线程池,可以有效地管理和复用线程,减少创建销毁线程的开销,提供统一的并发任务提交和执行策略。

案例示例:

  1. 简单线程创建示例

    class MyThread extends Thread {public void run() {System.out.println("线程正在运行...");}public static void main(String[] args) {MyThread t = new MyThread();t.start();}
    }
    
  2. 使用Runnable接口创建线程

    class RunnableExample implements Runnable {@Overridepublic void run() {System.out.println("Runnable接口创建的线程运行中...");}public static void main(String[] args) {Thread thread = new Thread(new RunnableExample());thread.start();}
    }
    
  3. 线程同步示例

    class Counter {private int count = 0;public synchronized void increment() {count++;}
    }class IncrementThread extends Thread {private final Counter counter;IncrementThread(Counter counter) {this.counter = counter;}@Overridepublic void run() {for (int i = 0; i < 1000; i++) {counter.increment();}}
    }public static void main(String[] args) {Counter counter = new Counter();Thread thread1 = new IncrementThread(counter);Thread thread2 = new IncrementThread(counter);thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("最终计数:" + counter.count);
    }
    
  4. 线程池使用示例

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {Runnable worker = new TaskWithResult(i);executor.execute(worker);}executor.shutdown(); // 关闭线程池不再接收新任务while (!executor.isTerminated()) {// 等待所有任务完成}System.out.println("所有任务已完成");}
    }class TaskWithResult implements Runnable {private int taskId;public TaskWithResult(int id) {this.taskId = id;}@Overridepublic void run() {System.out.println("线程 " + Thread.currentThread().getId() + " 正在处理任务:" + taskId);}
    }
    

通过这些要点和案例,学习者可以逐步掌握Java多线程编程的基本技巧和最佳实践,进而能够编写出高效、安全的并发程序。

Java多线程编程还包括更多的高级特性和实用技巧

当然,除了上面提到的内容外,Java多线程编程还包括更多的高级特性和实用技巧:

高级主题:

  1. volatile关键字

    • volatile关键字确保了共享变量的可见性和有序性,主要用于解决多线程间的内存可见性问题。
  2. 原子操作类

    • java.util.concurrent.atomic包下提供的原子操作类如AtomicIntegerAtomicLong等,它们提供了一种线程安全的、无锁的方式来更新基本类型的值。
  3. Future与FutureTask

    • Future接口表示异步计算的结果,通过它可以取消任务的执行,查询任务是否已经完成,获取结果等。
    • FutureTask实现了Future接口和Runnable接口,可以作为一个Runnable被提交到线程池执行,并能获取到线程执行结果。
  4. 线程中断

    • 通过调用Thread.interrupt()方法可以中断线程,线程应该适时检查Thread.interrupted()isInterrupted()来响应中断请求。
  5. 守护线程(Daemon Thread)

    • 守护线程是一种特殊的线程,它的特点是当所有非守护线程都结束后,JVM会自动结束守护线程,即使守护线程还在运行。
  6. 线程局部变量(ThreadLocal)

    • ThreadLocal类为每个线程维护了一个独立的副本,每个线程都可以修改自己的副本而不会影响其他线程。

实用案例:

  1. 使用Future获取线程执行结果

    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<String> future = executor.submit(new Callable<String>() {@Overridepublic String call() throws Exception {// 执行耗时任务Thread.sleep(1000);return "Task Result";}
    });// 主线程继续执行其他任务...
    // ...try {System.out.println("Future result: " + future.get()); // 获取线程执行结果
    } catch (InterruptedException | ExecutionException e) {e.printStackTrace();
    }executor.shutdown();
    
  2. 使用volatile解决可见性问题

    class VolatileExample {private volatile boolean ready;private int number;public void prepare() {// 准备数据number = 42;ready = true; // 设置标志位}public void printNumber() {while (!ready) { // 当ready为true时退出循环Thread.yield();}System.out.println(number);}
    }
    
  3. 使用ThreadLocal保存线程独享数据

    public class ThreadLocalExample {public static final ThreadLocal<UserContext> USER_CONTEXT = new ThreadLocal<>();public static void setUserContext(UserContext context) {USER_CONTEXT.set(context);}public static UserContext getUserContext() {return USER_CONTEXT.get();}
    }// 在处理用户请求的线程中保存用户上下文
    ThreadLocalExample.setUserContext(new UserContext(userId));// 在需要的地方获取用户上下文
    UserContext userContext = ThreadLocalExample.getUserContext();
    

以上都是Java多线程编程的重要知识点和应用场景,实际使用时应根据需求选择合适的技术手段来保证程序的正确性和效率。同时,对于线程安全问题,还应充分考虑死锁、活锁、饥饿等问题,避免在并发环境中出现难以预料的问题。

线程池的高级用法和配置:

  1. 线程池的拒绝策略

    • 当线程池的任务队列满并且线程池的线程数目达到最大时,新提交的任务将会被拒绝。Java提供了四种预定义的拒绝策略:

      • AbortPolicy(默认):抛出RejectedExecutionException异常。
      • CallerRunsPolicy:调用者所在的线程执行任务。
      • DiscardPolicy:直接丢弃任务,没有任何异常信息。
      • DiscardOldestPolicy:抛弃队列中最老的任务,尝试重新提交当前任务。
    • 也可以自定义拒绝策略,实现RejectedExecutionHandler接口。

  2. 定时任务与周期任务

    • ScheduledExecutorService接口提供了定时任务和周期任务的功能,可以使用Executors.newScheduledThreadPool()创建一个定长线程池,支持定时及周期性任务执行。

    • 示例:

      ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);// 延迟3秒后执行一次
      executor.schedule(new Runnable() {@Overridepublic void run() {System.out.println("延迟执行的任务");}
      }, 3, TimeUnit.SECONDS);// 每隔2秒执行一次
      executor.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("周期执行的任务");}
      }, 0, 2, TimeUnit.SECONDS);// 在程序结束前关闭线程池
      executor.shutdown();
      
  3. 线程池监控与分析

    • ThreadPoolExecutor提供了getPoolSize()getActiveCount()getCompletedTaskCount()等方法用于获取线程池状态信息。
    • 可以通过java.util.concurrent.ThreadPoolExecutorMXBean或JMX(Java Management Extensions)进行更深度的监控和管理。

线程安全的最佳实践:

  1. 不可变对象

    • 使用不可变对象可以天然地保证线程安全,因为一旦对象创建后,其状态就不会再发生变化。
  2. 并发容器

    • java.util.concurrent包下提供的并发容器,如ConcurrentHashMapCopyOnWriteArrayListBlockingQueue等,设计上即考虑到线程安全问题,因此在多线程环境下首选这些容器。
  3. 双重检查锁定(Double-Checked Locking)

    • 用于优化懒汉式单例模式的线程安全性,仅在需要实例时才进行同步操作。
  4. 细粒度锁

    • 尽可能减小锁的粒度,例如使用ReentrantReadWriteLock读写锁分离读写操作,提高并发效率。

总结:

深入学习Java多线程编程不仅要理解线程生命周期、线程创建、线程同步、线程间的通信与协作等基础概念,还需熟练掌握线程池的使用,以及如何设计和实现线程安全的代码。同时,针对特定场景选择合适的并发工具和设计模式也是提升并发程序性能的关键。在实践中不断加深对多线程的理解,并时刻注意排查和预防潜在的并发问题。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/272437.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

防患未然,OceanBase巡检工具应用实践——《OceanBase诊断系列》之五

1. OceanBase为什么要做巡检功能 尽管OceanBase拥有很好的MySQL兼容性&#xff0c;但在长期的生产环境中&#xff0c;部署不符合标准规范、硬件支持异常&#xff0c;或配置项错误等问题&#xff0c;这些短期不会出现的问题&#xff0c;仍会对数据库集群构成潜在的巨大风险。为…

血泪教训双非计算机考研避坑指南

记住&#xff0c;考研不是要考多少分&#xff0c;而是要上岸&#xff0c;上岸&#xff0c;上岸&#xff01;&#xff01;&#x1f621; 一、坏、渣、难、险&#xff0c;一律打咩 坏: 歧视本科院校‼️ 这个就不用多说了&#xff0c;你明明付出了大于等于别人的努力&#xff0c;…

猫头虎分享已解决Bug || 数据中心断电:PowerLoss, DataCenterBlackout

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

运维打工人,兼职跑外卖的第二个周末

北京&#xff0c;晴&#xff0c;西南风1级。 前序 今天天气还行&#xff0c;赶紧起来&#xff0c;把衣服都洗洗&#xff0c;准备准备&#xff0c;去田老师吃饭早饭了。 一个甜饼、一个茶叶蛋、3元自助粥花费7.5。5个5挺吉利的。 跑外卖的意义 两个字减肥&#xff0c;记录刚入…

JavaWeb03-HTTP协议,Tomcat,Servlet

目录 一、HTTP协议 1.概述 2.特点 3.请求数据格式 &#xff08;1&#xff09;请求行 &#xff08;2&#xff09;请求头 &#xff08;3&#xff09;请求体 &#xff08;4&#xff09;常见请求头 &#xff08;5&#xff09;GET和POST请求区别 4.响应数据格式 &#xf…

分销商城微信小程序:用户粘性增强,促进复购率提升

在数字化浪潮的推动下&#xff0c;微信小程序作为一种轻便、高效的移动应用形式&#xff0c;正成为越来越多企业开展电商业务的重要平台。而分销商城微信小程序的出现&#xff0c;更是为企业带来了前所未有的机遇。通过分销商城微信小程序&#xff0c;企业不仅能够拓宽销售渠道…

PyQt5实现远程更新exe可执行文件

PyQt5实现远程下载更新exe可执行文件 1、实现流程 1、获取远程http地址 2、获取需要更新的exe文件 3、点击更新 4、把exe强关闭 5、下载文件 6、更新2、效果图 3、示例代码 conf.ini配置文件: {"http_address_edit_value": "http://xxx.com/xxx/xxx.exe&qu…

数据结构从入门到精通——队列

队列 前言一、队列1.1队列的概念及结构1.2队列的实现1.3队列的实现1.4扩展 二、队列面试题三、队列的具体实现代码Queue.hQueue.ctest.c队列的初始化队列的销毁入队列出队列返回队头元素返回队尾元素检测队列是否为空检测元素个数 前言 队列是一种特殊的线性数据结构&#xff…

【蓝桥杯-单片机】基础模块LED和按键

文章目录 【蓝桥杯-单片机】Led、按键等基础模块01 前置准备&#xff08;1&#xff09;新建工程&#xff08;4&#xff09;编写程序 02 基础模块&#xff1a;LED&#xff08;0&#xff09;LED原理图&#xff08;1&#xff09;对P1整体赋值&#xff0c;控制所有的LED灯&#xff…

three.js如何实现简易3D机房?(一)基础准备-下

接上一篇&#xff1a; three.js如何实现简易3D机房&#xff1f;&#xff08;一&#xff09;基础准备-上&#xff1a;http://t.csdnimg.cn/MCrFZ 目录 四、按需引入 五、导入模型 四、按需引入 index.vue文件中 <template><div class"three-area">&l…

算法第二十五天-寻找排序数组中的最小值

寻找排序数组中的最小值 题目要求 解题思路 二分法 代码 class Solution:def findMin(self, nums: List[int]) -> int:low, high 0, len(nums) - 1while low < high:pivot low (high - low) // 2if nums[pivot] < nums[high]:high pivot else:low pivot 1re…

计算两帧雷达数据之间的变换矩阵

文章目录 package.xmlCMakeLists.txtpoint_cloud_registration.cc运行结果 package.xml <?xml version"1.0"?> <package format"2"><name>point_cloud_registration</name><version>0.0.0</version><descriptio…

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的按键扫描、数码管显示按键值、显示按键LED应用

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的按键扫描、数码管显示按键值、显示按键LED应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍TM1638键盘…

Spring Boot中实现图片上传功能的两种策略

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

js 清空数组的方法

1、直接赋值空数组 let array [1, 2, 3, 4, 5]; array []; 这种方法并不推荐&#xff0c;如下图所示&#xff1a; 虽然a数组确实变为了空数组&#xff0c;但这种方法只是修改了a的指向&#xff0c;把a指向一个新的空数组&#xff0c;然而[1,2,3,4,5]这个数组并没有被清除&a…

Matlab偏微分方程拟合 | 完整源码 | 视频教程

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法&#xff0c;并提供所有案例完整源码&#xff1b;2.…

Python——与Matlab对应的Python版本

参考资料&#xff1a; Python——与Matlab对应的Python版本

基于java+springboot+vue实现的学生信息管理系统(文末源码+Lw+ppt)23-54

摘 要 人类现已进入21世纪&#xff0c;科技日新月异&#xff0c;经济、信息等方面都取得了长足的进步&#xff0c;特别是信息网络技术的飞速发展&#xff0c;对政治、经济、军事、文化等方面都产生了很大的影响。 利用计算机网络的便利&#xff0c;开发一套基于java的大学生…

第十篇 - 如何利用人工智能技术做好营销流量整形管理?(Traffic Shaping)- 我为什么要翻译介绍美国人工智能科技巨头IAB公司

IAB平台&#xff0c;使命和功能 IAB成立于1996年&#xff0c;总部位于纽约市​​​​​​​。 作为美国的人工智能科技巨头社会媒体和营销专业平台公司&#xff0c;互动广告局&#xff08;IAB- the Interactive Advertising Bureau&#xff09;自1996年成立以来&#xff0c;先…

【蓝桥杯】蓝桥杯算法复习(一)

&#x1f600;大家好&#xff0c;我是白晨&#xff0c;一个不是很能熬夜&#x1f62b;&#xff0c;但是也想日更的人✈。如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下&#x1f440;白晨吧&#xff01;你的支持就是我最大的动力&#xff01;&#x1f4…