感谢这位博主解去了我多年来的心中疑惑,我是参考了这位博主再总结写的博文。
https://blog.csdn.net/ThinkWon/article/details/102020811
常常在开发中用过多线程,简单类的多线程,但从来只是会用,却不知其深意,今日在看了某博主的文章后,感慨良多,心有体会,决会做个笔录,以效勉之。
多线程用的好,事半功倍,用的不好便是功半事倍,但大多数人都是只是简单用之,稍复杂点,便是拖累了整个系统。
1.什么是并发?
粗暴的理解就是:并发编程就是在充分利用多核CPU的计算能力。
优点:方便进行业务拆分,提升系统并发能力和性能。
百万级、千万级的并发量,多线程并发编程,只是开发高并发系统的基础而已。
缺点:内存泄露,上下文切换,死锁,线程不安全
2.什么是上下文切换?
上下文切换就是内容从保存到再加载。
详细说明一下:
多线程编程,一程个数>CPU核心个数,而一个CPU只能被一个线程调用,为了让每个线程都得以被使用,CPU的策略就是,为每个线程分配时间并轮流,时间单位通常为几十毫秒,当一个线程的时间片用完后就会重新处理就绪状态,让给其它线程使用,这个过程就是上下文切换。
减少上下文切换的解决方法:1.无锁并发编程
2.将系统布署在LINUX系统上,LINUX系统的优点之一,上下文切换和模式切换的时间消耗非常少。
3.什么是阻塞和非阻塞?
阻塞:调用发出去后,消息返回前,线/进程被挂起,直到返回之前,线/进程才被激活。
非阻塞:调用发出去后,不会阻塞当前线/进程,即非挂起状态,而会立即返回。
4.什么是同步和异步?
同步:当一个调用发出去,一直等待调用结果返回后,才能进行后续操作。
异步:当一个调用发出去,不管它有没有完成,都会继续执行下面的代码。
异步用callback来获得结果。
5.什么是临界区?
代表公共资源,共享数据,可以被多个线程使用,但多个线程使用时,一旦被某个线程使用,其它线程必须等。
用的不好的话这种情况极易发生死锁,严重的后果就是系统将不可用,那么我们该怎么注意呢?请见如下:
1.避免一个线程同时获得多个锁。
2.避免一个线程内部占有多个临界区资源。
3.尽量一个线程一个锁一个资源。
4.尝试定时锁,lock.tryLock(timeOut)
5.数据库锁,加锁/解锁在一个数据库连接里,否则解锁将失败。
6.并发,并行和串午的解释?
并发:同一时间段 ,多个任务交替执行(单位时间内不一定同时执行)。
并行:同一时间段 ,同时执行(在多个CPU计算机中)。
串行:同个任务/线程,由同一个线程顺序执行,不存在死锁,不存在不安全,不存在临界区。
看完了上面内容,各位应该也是明白了,除去了心中疑惑,现附上线程死锁的示例代码。
public class DeadLockDemo {
private static String resource_a = "A";
private static String resource_b = "B";
public static void main(String[] args) {
deadLock();
}
public static void deadLock() {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
synchronized (resource_a) {
System.out.println("get resource a");
try {
Thread.sleep(3000);
synchronized (resource_b) {
System.out.println("get resource b");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
synchronized (resource_b) {
System.out.println("get resource b");
synchronized (resource_a) {
System.out.println("get resource a");
}
}
}
});
threadA.start();
threadB.start();
}
}
再附件报错信息:
"Thread-1":
waiting to lock monitor 0x000000000b695360 (object 0x00000007d5ff53a8, a java.lang.String),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x000000000b697c10 (object 0x00000007d5ff53d8, a java.lang.String),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at learn.DeadLockDemo$2.run(DeadLockDemo.java:34)
- waiting to lock <0x00000007d5ff53a8(a java.lang.String)
- locked <0x00000007d5ff53d8(a java.lang.String)
at java.lang.Thread.run(Thread.java:722)
"Thread-0":
at learn.DeadLockDemo$1.run(DeadLockDemo.java:20)
- waiting to lock <0x00000007d5ff53d8(a java.lang.String)
- locked <0x00000007d5ff53a8(a java.lang.String)
at java.lang.Thread.run(Thread.java:722)
Found 1 deadlock.
————————————————