python爬虫系统 项目,《零基础Python实战实现爬虫系统项目实战》(最新)

本文详细介绍了Java并发编程中的上下文切换和死锁问题。上下文切换涉及到线程状态的保存和加载,增加系统开销,可以通过减少线程数量和使用无锁编程来降低。死锁则是多个线程互相等待对方释放资源导致的僵局,通过理解四个必要条件可以避免死锁。文中给出了一个简单的死锁代码示例,帮助理解死锁的产生过程。
摘要由CSDN通过智能技术生成

前言

今天是2019年03月19日,最近读了不少书,《Java并发编程的艺术》就是其中一本,这本书比较适合入门,讲的非常简单。这本书一共有11章,我已经看完第一遍了,有的章节看了两三遍,所以通过博客的形式梳理一番阅读过的内容。我不会把整本书的内容都放进来,我想写下来的是我理解了的部分,能够整理成块的内容。

并发编程就是用多线程的技术去达到更好的效率,但多线程必可避免会带来一些挑战,本文介绍了其中的两个挑战:

上下文切换

死锁

上下文切换

上下文切换的概念和影响

单核CPU的情况下,同一时间只能有一个线程占有CPU的时间片,那么线程在执行任务时,执行到一半就切换到另一个线程去了,下次回来这个线程的时候,任务还得继续执行,而跟这个任务相关的状态就需要重新被加载。上下文切换的开销在于,切换线程时前一个线程的状态的保存和切换到的线程的加载。

如何减少上下文切换的次数

无锁编程,如CAS等

减少线程数量

使用协程,在单一线程中进行多任务的切换

Java减少上下文切换实战

用jps打出当前java虚拟机中的各种进程

用jstack命令把某个进程的线程状态保存到一个文件中

jstack 5313 > /root/jstack/machine_status_dump

用grep结合相关命令统计线程状态

grep java.lang.Thread.State machine_status_dump | awk '{print $2$3$4$5}'| sort | uniq -c

如果WATING状态的线程数量过多,考虑减少线程池的核心线程数量。当然在本例中只有1+10个WATING的线程,相对而言还不算太多。

死锁

下面通过一道面试题的形式来阐述这个问题,有时候面试官会让手写一个死锁代码出来。

写代码其实考察的是背后对这个代码的思想的理解,我们首先得理解死锁是怎样产生的。在学习操作系统的时候,我们知道,死锁产生有四个条件。

资源互斥:某个资源只能允许一个进程访问,这个进程在访问时,其他进程不可以访问

占有且等待:占有一部分资源的进程,同时还缺一部分资源没拿到,在等待其他进程释放

不可抢占:资源被一个进程占有时,不能被抢走

循环等待:存在一个循环链,使得链中的所有进程都在等待前一个进程释放资源,形成了循环等待,大家都无法释放资源。

因此,在Java中,要写一个死锁代码,我们需要定义互斥(同一时刻只能被一个线程持有,这里通过Java的synchronize来实现)的资源A和B,要定义两个线程C和D,以synchronize的形式对资源A上锁,使得只有线程C能持有资源A,线程C持有A后,线程A的run方法里的代码还应该试图去持有资源B。而这时候得让资源B已经被线程D持有,同时线程D的run方法里也要试图去持有资源A,这样线程C和D就形成了循环等待。

线程C持有A等待B,线程D持有B等待A,两者都不释放,构成死锁。

这就在线程C获取到资源B之前,synchronize同步代码块不能往下执行了,也就无法释放掉线程C持有的资源A。下面看一下代码实现。

public class DeadLock {

private static String A="A";

private static String B="B";

public static void main(String[] args){

new Thread(()->{

synchronized (A){

System.out.println("线程C获取到资源A");

try {

Thread.sleep(1000);  //本线程等1秒让线程D能够获取到资源B

}catch (Exception e){

e.printStackTrace();

}

synchronized (B){

System.out.println("线程C获取到资源B");

}

}

}).start();

new Thread(()->{

synchronized (B){

System.out.println("线程D获取到资源B");

try {

Thread.sleep(1000); //本线程等1秒让线程C能够获取到资源A

}catch (Exception e){

e.printStackTrace();

}

synchronized (A){

System.out.println("线程D获取到资源A");

}

}

}).start();

}

}

执行结果:

线程C获取到资源A

线程D获取到资源B

---------------------

作者:kukubao207

来源:CSDN

原文:https://blog.csdn.net/kukubao207/article/details/88660833

版权声明:本文为博主原创文章,转载请附上博文链接!

标签:实战,Python,爬虫,获取,死锁,线程,切换,进程,资源

来源: https://blog.csdn.net/weixin_44961199/article/details/90031116

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值