Java多线程1-初识多线程

//阅读学习《Java并发编程的艺术》笔记,第一章

序、进程与线程

1、定义:

    独立运行的程序叫做进程,进程里面的运算单元都是线程组成的 进程从规模上大于线程,进程包含线程,一个进程由一到多个线程组成

2、代码理解:

    主线程拷贝主方法压入栈中 在主方法中启动了两个线程t1、t2,之后相互独立互不干扰 start()表明进入就绪状态,何时执行取决于何时被CPU选中

3、线程切换及原因:

    每一个核同一时间只能做一件事情,所以想要执行任务需要获取时间片,切换执行 等待时间片时间越长,优先级越高 windows一般是变长时间片,Linux一般是定长时间片 上下文切换:上次执行到哪里,记录下来,下次还从这里开始。所以任务从保存到再加载的过程就是一次上下文切换。 线程切换需要将近1ms,是有时间消耗的,所以多线程不一定比单线程快 如果在单核CPU且没有CPU浪费的情况下,单线程比多线程快,因为线程切换有时间消耗 现代电脑双核或四核,使用多线程相当于把其他核也利用起来,所以多线程会比单线程快

4、多线程的使用场景:

1、实际业务需要

2、CPU有严重浪费的时候

使用多线程会提高CPU的利用率

实际场景:网络爬虫,数据库操作

5、主要看CPU浪费占比

假设每个任务CPU空闲10ms,已知多线程切换有时间消耗。

Java处理需要3000ms,CPU浪费等待了10ms,占比太小,使用多线程并不合适。

不一定CPU浪费的时间多就用多线程,得看CPU浪费占总时间的比例是多少,占比大用多线程才合适。

不合适用多线程实际场景:图像处理、视频处理

一、并发编程的挑战

Lmbench3性能分析工具,面试加分

1、如何减少上下文切换:

减少上下文切换的方法有无锁并发编程、CAS算法、使用最少线程和使用协程。

无锁并发编程。多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。

CAS算法。Java的Atomic包使用CAS算法来更新数据,而不需要加锁。

使用最少线程。避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。

协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

2、减少上下文切换实战

dump:查看当前快照信息

指令:sudo -u admin /opt/ifeve/java/bin/jstack 31177 > /home/tengfei.fangtf/dump17

意为:sudo是linux中的命令,用管理员身份使用jdk的/opt/ifeve/java/bin/jstack指令把进程pid为31177的快照信息存到该路径下,命名为dump17

指令:grep java.lang.Thread.State dump17 | awk {print $2$3$4$5} | sort | uniq -c

意为:grep筛选按照这种格式输出,unip -c表示统计

如何根据进程id查看线程信息?

答案就是上面的两条指令。

3、死锁

    synchronized上锁,执行时加锁,执行完后将其释放,使用引用类型上锁,不能用基本类型 为何导致死锁:上锁后互相等待对方资源

避免死锁的几个常见方法:

1、避免一个线程同时获取多个锁。

2、避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。

3、尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。

4、对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。


第一章的笔记end!

经验分享 程序员 微信小程序 职场和发展