Skip to content

Commit ff5e60b

Browse files
committed
juc
1 parent d6e42e3 commit ff5e60b

File tree

44 files changed

+2237
-2086
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2237
-2086
lines changed

docs/interview/JUC-FAQ.md

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ JUC 面试题总共围绕的就这么几部分
3535
- **并发:** 同一时间段,多个任务都在执行 (单位时间内不一定同时执行);
3636
- **并行:** 单位时间内,多个任务同时执行。
3737

38-
38+
![](https://tva1.sinaimg.cn/large/0081Kckwly1gkc43bnvvlj31wc0prabv.jpg)
3939

4040
### 说下同步、异步、阻塞和非阻塞
4141

42-
# 同步与异步#
42+
## 同步与异步
4343

4444
首先来解释同步和异步的概念,这两个概念与消息的通知机制有关。也就是**同步与异步主要是从消息通知机制角度来说的**
4545

@@ -95,6 +95,24 @@ Linux 相比与其他操作系统(包括其他类 Unix 系统)有很多的
9595

9696

9797

98+
### 什么是线程的上下文切换?
99+
100+
对于单核 CPU,CPU 在一个时刻只能运行一个线程,当在运行一个线程的 过程中转去运行另外一个线程,这个叫做线程上下文切换(对于进程也是类似)。
101+
102+
线程上下文切换过程中会记录程序计数器、**CPU** 寄存器的状态等数据。
103+
104+
虽然多线程可以使得任务执行的效率得到提升,但是由于在线程切换时同 样会带来一定的开销代价,并且多个线程会导致系统资源占用的增加,所以在 进行多线程编程时要注意这些因素。
105+
106+
107+
108+
### 用户线程和守护线程有什么区别?
109+
110+
当我们在 Java 程序中创建一个线程,它就被称为用户线程。将一个用户线 程设置为守护线程的方法就是在调用 **start()**方法之前,调用对象的 setDamon(true)方法。一个守护线程是在后台执行并且不会阻止 JVM 终止的 线程,守护线程的作用是为其他线程的运行提供便利服务。当没有用户线程在 运行的时候,**JVM** 关闭程序并且退出。一个守护线程创建的子线程依然是守护 线程。
111+
112+
守护线程的一个典型例子就是垃圾回收器。
113+
114+
115+
98116
### 如何在 Windows 和 Linux 上查找哪个线程 cpu 利用率最高?
99117

100118
windows上面用任务管理器看,linux下可以用 top 这个工具看。
@@ -183,6 +201,16 @@ new 一个 Thread,线程进入了新建状态;调用 start() 方法,会启
183201

184202
https://www.cnblogs.com/hapjin/p/5492619.html
185203

204+
205+
206+
### **Java** 中 interrupted() 和 **isInterrupted()**方法的区 别?
207+
208+
二个方法都是判断线程是否停止的方法。
209+
210+
1. 前者是静态方法,后者是非静态方法。interrupted 是作用于当前正在运 行的线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在 A 线程中去调用 B 线程对象的 isInterrupted 方法,此时,当前正在运行的线程就是 A 线程。)
211+
212+
2. 前者会将中断状态清除而后者不会。
213+
186214
------
187215

188216

@@ -1817,4 +1845,85 @@ static class Entry extends WeakReference<ThreadLocal<?>> {
18171845

18181846

18191847

1820-
1848+
### 网站的高并发,大流量访问怎么解决?
1849+
1850+
1. HTML 页面静态化
1851+
1852+
访问频率较高但内容变动较小,使用网站 HTML 静态化方案来优化访问速度。将社区 内的帖子、文章进行实时的静态化,有更新的时候再重新静态化也是大量使用的策略。
1853+
1854+
优势:
1855+
一、减轻服务器负担。
1856+
1857+
二、加快页面打开速度,静态页面无需访问数据库,打开速度较动态页面有明显提高;
1858+
1859+
三、很多搜索引擎都会优先收录静态页面,不仅被收录的快,还收录的全,容易被搜索引擎找到;
1860+
1861+
四、HTML 静态页面不会受程序相关漏洞的影响,减少攻击 ,提高安全性。
1862+
1863+
2. 图片服务器和应用服务器相分离
1864+
1865+
现在很多的网站上都会用到大量的图片,而图片是网页传输中占主要的数据量,也是影 响网站性能的主要因素。因此很多网站都会将图片存储从网站中分离出来,另外架构一个 或多个服务器来存储图片,将图片放到一个虚拟目录中,而网页上的图片都用一个 URL 地 址来指向这些服务器上的图片的地址,这样的话网站的性能就明显提高了。
1866+
1867+
优势:
1868+
一、 分担 Web 服务器的 I/O 负载-将耗费资源的图片服务分离出来,提高服务器的性能和稳定性。
1869+
1870+
二、 能够专门对图片服务器进行优化-为图片服务设置有针对性的缓存方案,减少带宽 成本,提高访问速度。
1871+
1872+
三、 提高网站的可扩展性-通过增加图片服务器,提高图片吞吐能力。
1873+
1874+
3. 数据库 数据库层面的优化,读写分离,分库分表
1875+
1876+
4. 缓存
1877+
1878+
尽量使用缓存,包括用户缓存,信息缓存等,多花点内存来做缓存,可以大量减少与 数据库的交互,提高性能。
1879+
1880+
假如我们能减少数据库频繁的访问,那对系统肯定大大有利的。比如一个电子商务系 统的商品搜索,如果某个关键字的商品经常被搜,那就可以考虑这部分商品列表存放到缓 存(内存中去),这样不用每次访问数据库,性能大大增加。
1881+
1882+
5. 镜像
1883+
1884+
镜像是冗余的一种类型,一个磁盘上的数据在另一个磁盘上存在一个完全相同的副本 即为镜像。
1885+
1886+
6. 负载均衡
1887+
1888+
在网站高并发访问的场景下,使用负载均衡技术(负载均衡服务器)为一个应用构建 一个由多台服务器组成的服务器集群,将并发访问请求分发到多台服务器上处理,避免单 一服务器因负载压力过大而响应缓慢,使用户请求具有更好的响应延迟特性。
1889+
1890+
7. 并发控制 加锁,如乐观锁和悲观锁。
1891+
1892+
8. 消息队列
1893+
通过 mq 一个一个排队方式,跟 12306 一样。
1894+
1895+
1896+
1897+
### 订票系统,某车次只有一张火车票,假定有 **1w** 个人同 时打开 **12306** 网站来订票,如何解决并发问题?(可扩展 到任何高并发网站要考虑的并发读写问题)。
1898+
1899+
不但要保证 1w 个人能同时看到有票(数据的可读性),还要保证最终只能 由一个人买到票(数据的排他性)。
1900+
1901+
使用数据库层面的并发访问控制机制。采用乐观锁即可解决此问题。乐观 锁意思是不锁定表的情况下,利用业务的控制来解决并发问题,这样既保证数 据的并发可读性,又保证保存数据的排他性,保证性能的同时解决了并发带来 的脏数据问题。hibernate 中实现乐观锁。
1902+
1903+
银行两操作员同时操作同一账户就是典型的例子。比如 AB 操作员同 时读取一余额为 1000 元的账户,A 操作员为该账户增加 100 元,B 操作员同时 为该账户减去 50元,A先提交,B后提交。最后实际账户余额为1000-50=950 元,但本该为 1000+100-50=1050。这就是典型的并发问题。如何解决?可以用锁。
1904+
1905+
1906+
1907+
### 如果不用锁机制如何实现共享数据访问。(不要用锁,不要用 **sychronized** 块或者方法,也不要直接使用 **jdk** 提供的线程安全 的数据结构,需要自己实现一个类来保证多个线程同时读写这个类 中的共享数据是线程安全的,怎么办?)
1908+
1909+
无锁化编程的常用方法:硬件**CPU**同步原语CAS(Compare and Swap),如无锁栈,无锁队列(ConcurrentLinkedQueue)等等。现在 几乎所有的 CPU 指令都支持 CAS 的原子操作,X86 下对应的是 CMPXCHG 汇 编指令,处理器执行 CMPXCHG 指令是一个原子性操作。有了这个原子操作, 我们就可以用其来实现各种无锁(lock free)的数据结构。
1910+
1911+
CAS 实现了区别于 sychronized 同步锁的一种乐观锁,当多个线程尝试使 用 CAS 同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线 程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再 次尝试。CAS3 个操作数,内存值 V,旧的预期值 A,要修改后的新值 B。 当且仅当预期值 A 和内存值 V 相同时,将内存值 V 修改为 B,否则什么都不做。 其实 CAS 也算是有锁操作,只不过是由 CPU 来触发,比 synchronized 性能 好的多。CAS 的关键点在于,系统在硬件层面保证了比较并交换操作的原子性, 处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操 作。CAS 是非阻塞算法的一种常见实现。
1912+
1913+
一个线程间共享的变量,首先在主存中会保留一份,然后每个线程的工作 内存也会保留一份副本。这里说的预期值,就是线程保留的副本。当该线程从 主存中获取该变量的值后,主存中该变量可能已经被其他线程刷新了,但是该 线程工作内存中该变量却还是原来的值,这就是所谓的预期值了。当你要用 CAS 刷新该值的时候,如果发现线程工作内存和主存中不一致了,就会失败,如果 一致,就可以更新成功。
1914+
1915+
**Atomic** 包提供了一系列原子类。这些类可以保证多线程环境下,当某个 线程在执行atomic的方法时,不会被其他线程打断,而别的线程就像自旋锁一 样,一直等到该方法执行完成,才由 JVM 从等待队列中选择一个线程执行。 Atomic 类在软件层面上是非阻塞的,它的原子性其实是在硬件层面上借助相关 的指令来保证的。
1916+
1917+
1918+
1919+
### 写出 **3** 条你遵循的多线程最佳实践。
1920+
1921+
1. 给线程起个有意义的名字。
1922+
1923+
2. 避免锁定和缩小同步的范围 。
1924+
1925+
相对于同步方法我更喜欢同步块,它给我拥有对锁的绝对控制权。
1926+
1927+
3. 多用同步辅助类,少用 **wait****notify**
1928+
4. 多用并发容器,少用同步容器。
1929+
如果下一次你需要用到 map,你应该首先想到用 ConcurrentHashMap

docs/java/JUC/readJUC.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@
1414
- [CountDownLatch、CyclicBarrier、Semaphore](java/JUC/CountDownLatch、CyclicBarrier、Semaphore.md)
1515
- [AQS](java/JUC/AQS.md)
1616

17-
![J.U.C 类分类](https://img-blog.csdn.net/20170126201206425?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDg1MzI2MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
17+
![J.U.C 类分类](https://img-blog.csdn.net/20170126201206425?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDg1MzI2MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
18+
19+
![](https://tva1.sinaimg.cn/large/0081Kckwly1gkc498bgkkj310r0u0dhr.jpg)

node_modules/@vuepress/core/.temp/app-enhancers/global-components-10.js renamed to node_modules/@vuepress/core/.temp/app-enhancers/global-components-9.js

File renamed without changes.

node_modules/@vuepress/core/.temp/internal/app-enhancers.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)