程序员:多并发基础的线程【详细版】

阅读本文约“12分钟”

适读人群:Java初级

学习笔记

基础概念

线程是无处不在的

先说说几个基本的概念吧

一个进程中可以包含多个线程,同一个进程中的线程共享该进程所申请到的资源,如内存空间和文件句柄等

从JVM的角度来看,线程是进程中的一个组件(Component)

Java程序中任何一段代码总是执行在某个确定的线程中

Java中线程分为守护线程(Daemon Thread)和用户线程(User Thread)

用户线程:JVM正常停止前应用程序中的所有用户线程必须先停止完毕,否则JVM无法停止

守护线程:不会影响JVM的正常停止,通常执行一些重要性不高的任务,如监视其他线程的运行情况

在多线程的运行中,我们需要注意每个段代码是由哪一个线程去负责执行的,这关系到性能问题、线程安全

System.out.println("The ** method was executed by thread: " + Thread.currentThread().getName());

如上可以看看对应方法是哪个线程负责执行的,当然你可以创新一个新的线程,并由新的线程负责,来验证你的猜想

创建并运行

在Java中,一个线程就是一个java.lang.Thread的实例

创建一个Thread类,JVM会为这个线程实例分配两个调用栈(Call Stack)所需的内容空间

两个调用栈,一个用于跟踪Java代码间的调用关系,另一个用于跟踪Java代码对本地代码(即Native代码)的调用关系

假设我们在main方法中创建了一个新的线程,那么新的thread就是main线程的子线程,它们也就是父子线程关系

在默认情况下父线程为守护线程,则子线程也同样为守护,用户线程也是如此,当然你也可以通过setDaemon方法来修改这一属性

态与上下文切换

人这一生有很多种状态,线程也是一样的

我们可以通过getState方法获取,返回值是Enum(枚举)

而一个线程从RUNNABLE转换为BLOCKED、WAITING、TIMED_WAITING几个状态的过程就意味着上下文切换(Context Switch)

上下文信息:包括CPU的寄存器和程序计数器在某一时间点的内容等

就好像你在和父母打电话的时候,突然你女朋友打了进来,你果断接了女朋友的约会邀请,然后又重新接上父母这边的并续上刚刚的聊天内容

从RUNNABLE转到其他,上下文信息(聊天内容)需要先存储起来,然后再重新进入RUNABLE状态时,回复之前保存的线程的上下文信息(聊天内容),在保存和回复的过程就是上下文切换

在保存或恢复就是需要开销的,如CPU时间开销和CPU缓存内容失效等

你可以看看自己的Java程序运行时的上下文切换情况,我这边是win7,所以用了windows自带的perfmon

Linux也可以用perf命令查看

perf stat -e cpu-clock,task-clock,cs,cache-references,cache-misses java 你的程序名

线程监控

咱们需要把未知的东西变为已知的,黑盒变白盒

你可以尝试用JDK自身的jvisualvm监视

或是jmc也行

优劣

这个其实大家都基本了解,所以我不打算细讲来着

关于生命特征,可能就会涉及多种锁

死锁(Dead Lock):即都拥有自己的锁但是又在等对方的锁

T1(L1) 等 L2
T2(L2) 等 L1

活锁(Live Lock):一个线程一直尝试某个操作但是无果(就像部分暗恋、舔狗类似····,这个比喻是我和爱人说明后她给我的第一印象)

线程饥饿(Starvation):永远无法获得CPU执行机会,永远处于RUNNABLE状态的READY子状态。

相关术语

下次再说说,附录的synchronize和volatile。

我是MySelf,还在坚持学习技术与产品经理相关的知识,希望本文能给你带来新的知识点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值