文档章节

Java大佬带你详细了解,线程的应用及挑战

Java-飞鱼
 Java-飞鱼
发布于 06/25 21:47
字数 1887
阅读 61
收藏 4

文章简介

上一篇文章我们了解了进程和线程的发展历史、线程的生命周期、线程的优势和使用场景,这一篇,我们从Java层面更进一步了解线程的使用

内容导航

  • 并发编程的挑战
  • 线程在Java中的使用

一、并发编程的挑战

引入多线程的目的在第一篇提到过,就是为了充分利用CPU是的程序运行得更快,当然并不是说启动的线程越多越好。在实际使用多线程的时候,会面临非常多的挑战

线程安全问题

线程安全问题值的是当多个线程访问同一个对象时,如果不考虑这些运行时环境采用的调度方式或者这些线程将如何交替执行,并且在代码中不需要任何同步操作的情况下,这个类都能够表现出正确的行为,那么这个类就是线程安全的

比如下面的代码是一个单例模式,在代码的注释出,如果多个线程并发访问,则会出现多个实例。导致无法实现单例的效果

Java大佬带你详细了解,线程的应用及挑战

 

通常来说,我们把多线程编程中的线程安全问题归类成如下三个,至于每一个问题的本质,在后续的文章中我们会单独讲解

  • 原子性
  • 可见性
  • 有序性

上下文切换问题

在单核心CPU架构中,对于多线程的运行是基于CPU时间片切换来实现的伪并行。由于时间片非常短导致用户以为是多个线程并行执行。而一次上下文切换,实际就是当前线程执行一个时间片之后切换到另外一个线程,并且保存当前线程执行的状态这个过程。上下文切换会影响到线程的执行速度,对于系统来说意味着会消耗大量的CPU时间。

减少上下文切换的方式

  • 无锁并发编程,在多线程竞争锁时,会导致大量的上下文切换。避免使用锁去解决并发问题可以减少上下文切换
  • CAS算法,CAS是一种乐观锁机制,不需要加锁
  • 使用与硬件资源匹配合适的线程数

死锁

在解决线程安全问题的场景中,我们会比较多的考虑使用锁,因为它使用比较简单。但是锁的使用如果不恰当,则会引发死锁的可能性,一旦产生死锁,就会造成比较严重的问题:产生死锁的线程会一直占用锁资源,导致其他尝试获取锁的线程也发生死锁,造成系统崩溃以下是死锁的简单案例

Java大佬带你详细了解,线程的应用及挑战

 

通过jstack分析死锁

1. 首先通过jps获取当前运行的进程的pid

Java大佬带你详细了解,线程的应用及挑战

 

2. jstack打印堆栈信息,输入 jstack19004, 会打印如下日志,可以很明显看到死锁的信息提示

Java大佬带你详细了解,线程的应用及挑战

 

解决死锁的手段

  • 保证多个线程按照相同的顺序获取锁
  • 设置获取锁的超时时间,超过设定时间以后自动释放
  • 死锁检测

资源限制

资源限制主要指的是硬件资源和软件资源,在开发多线程应用时,程序的执行速度受限于这两个资源。硬件的资源限制无非就是磁盘、CPU、内存、网络;软件资源的限制有很多,比如数据库连接数、计算机能够支持的最大连接数等

资源限制导致的问题最直观的体现就是前面说的上下文切换,也就是CPU资源和线程资源的严重不均衡导致频繁上下文切换,反而会造成程序的运行速度下降

资源限制的主要解决方案,就是缺啥补啥。CPU不够用,可以增加CPU核心数;一台机器的资源有限,则增加多台机器来做集群。

二、线程在Java中的使用

在Java中实现多线程的方式比较简单,因为Java中提供了非常方便的API来实现多线程。

  • 继承Thread类实现多线程
  • 实现Runnable接口
  • 实现Callable接口通过Future包装器来创建Thread线程,这种是带返回值的线程
  • 使用线程池ExecutorService

继承Thread类

继承Thread类,然后重写run方法,在run方法中编写当前线程需要执行的逻辑。最后通过线程实例的start方法来启动一个线程

Java大佬带你详细了解,线程的应用及挑战

 

Thread类其实是实现了Runnable接口,因此Thread自己也是一个线程实例,但是我们不能直接用 newThread().start()去启动一个线程,原因很简单,Thread类中的run方法是没有实际意义的,只是一个调用通过构造函数传递寄来的另一个Runnable实现类的run方法,这块的具体演示会在Runnable接口的代码中看到

Java大佬带你详细了解,线程的应用及挑战

 

实现Runnable接口

如果需要使用线程的类已经继承了其他的类,那么按照Java的单一继承原则,无法再继承Thread类来实现线程,所以可以通过实现Runnable接口来实现多线程

Java大佬带你详细了解,线程的应用及挑战

 

上面的代码中,实现了Runnable接口,重写了run方法;接着为了能够启动RunnableDemo这个线程,必须要实例化一个Thread类,通过构造方法传递一个Runnable接口实现类去启动,Thread的run方法就会调用target.run来运行当前线程,代码在上面.

实现Callable接口

在有些多线程使用的场景中,我们有时候需要获取异步线程执行完毕以后的反馈结果,也许是主线程需要拿到子线程的执行结果来处理其他业务逻辑,也许是需要知道线程执行的状态。那么Callable接口可以很好的实现这个功能

Java大佬带你详细了解,线程的应用及挑战

 

在上面代码案例中的最后一行 task.get()就是获取线程的返回值,这个过程是阻塞的,当子线程还没有执行完的时候,主线程会一直阻塞直到结果返回

使用线程池

为了减少频繁创建线程和销毁线程带来的性能开销,在实际使用的时候我们会采用线程池来创建线程,在这里我不打算展开多线程的好处和原理,我会在后续的文章中单独说明。

Java大佬带你详细了解,线程的应用及挑战

 

pool.submit有几个重载方法,可以传递带返回值的线程实例,也可以传递不带返回值的线程实例,源代码如下

Java大佬带你详细了解,线程的应用及挑战

 

Java大佬带你详细了解,线程的应用及挑战

上图中的资料都是我精心录制视频,感兴趣的可以加入我的学习圈子:142019080 免费获取。希望能够在你接下来即将应对的的面试过程中能够尽到一份绵薄之力

© 著作权归作者所有

Java-飞鱼
粉丝 10
博文 22
码字总数 50833
作品 0
长沙
私信 提问
java程序中如何中断正在运行的线程?

最近有个问题一直困扰我,那就是如何中断java线程。 我从网上看到java线程的stop,pause,resume方法已经不提倡了。 然后如果只是简单的设置一个变量进行标识的话,又可能碰到线程sleep,无法...

snowdream
2012/01/16
5.9K
13
这是一份全面 & 详细的Android多线程知识总结指南

前言 多线程的应用在Android开发中是非常常见的,常用方法主要有: 今天,我将献上一份全面 & 详细的Android多线程学习指南,希望你们喜欢。 目录 1. 多线程基础知识 在了解Android多线程实现...

Carson_Ho
06/26
0
0
JVM Management API

JVM本 身提供了一组管理的API,通过该API,我们可以获取得到JVM内部主要运行信息,包括内存各代的数据、JVM当前所有线程及其栈相关信息等等。各种 JDK自带的剖析工具,包括jps、jstack、jin...

今幕明
2014/09/09
0
0
利用 Java dump 进行 JVM 故障诊断

引言 对于大型 java 应用程序来说,再精细的测试都难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现。...

candies
2014/03/03
0
0
大佬分享:180+道Java面试题目!含答案解析!

作者:我是offer 链接:https://www.nowcoder.com/discuss/84736 来源:牛客网 大厂常见问题 写视频点播网站文件下载接口 基础变量/数组写出模拟maven导入包过程 写出新变脸内存分配,模拟垃...

Java高级架构
2018/07/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Linux的基本命令

目录的操作命令(增删改查) 增: mkdir 目录名称; 查: ls 可以看到该目录下的所有的目录和文件 ls -a,可以看到该目录下的所有文件和目录,包括隐藏的 ls -l,可以看到该目录下的所有目录和...

凹凸凸
今天
2
0
在古老unix中增加新用户

Installing 4.3 BSD Quasijarus on SIMH 目标:要在4.3BSD中新增加用户dmr,指定目录/home/dmr,uid为10 gid=31(guest组,系统已建立) 4.3BSD还没有adduser或useradd 直接修改/etc/passwd...

wangxuwei
今天
2
0
Bootstrap(六)表单样式

基本样式 所有设置了 .form-control 类的 <input>、<textarea> 和 <select> 元素都将被默认设置宽度属性为 width: 100%;。 将 label 元素和前面提到的控件包裹在 .form-group 中可以获得最好...

ZeroBit
昨天
3
0
SSL 证书格式转换

SSL 证书格式转换 不同服务器情况下,需要不同的证书格式。 比如 pem 转 pfx。 pem在window 平台下可以导入,但是无法正常使用。 需要转换成pfx。 推荐在线转换工具,由中国数字证书网站提供...

DrChenXX
昨天
2
0
HAProxy

xx

Canaan_
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部