<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[徘徊在牛A与牛C之间的码农]]></title><description><![CDATA[[为梦想，不负韶华] 不要假装去努力，结果不会陪着你演戏]]></description><link>https://blog.youkuaiyun.com/zhanghai412</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; zhanghai412]]></copyright><item><title><![CDATA[Git push or git clone 443 ,10053等问题]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/118642743</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/118642743</guid><author>zhanghai412</author><pubDate>Sat, 10 Jul 2021 23:42:45 +0800</pubDate><description><![CDATA[1.常规参照https://blog.youkuaiyun.com/qq_37555071/article/details/114260533应该可以解决大部份问题

2.取消

3.以上都不行，设置git.exe管理员运行，

设置：

$ git config --system --unset credential.helper

第一个item需要，不然第二个命令无法执行。

设置完毕重新输入

git clone XXX 就会pop up出来让你输入用户名和密码的dialog了。

如果出现缺少证书...]]></description><category></category></item><item><title><![CDATA[git config命令使用]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/118638809</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/118638809</guid><author>zhanghai412</author><pubDate>Sat, 10 Jul 2021 18:27:27 +0800</pubDate><description><![CDATA[很详细的config 配置解释，有全局的，系统的，本地的

https://zhuanlan.zhihu.com/p/76467410
]]></description><category></category></item><item><title><![CDATA[Java多线程学习四十三：]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115710501</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115710501</guid><author>zhanghai412</author><pubDate>Wed, 14 Apr 2021 22:00:01 +0800</pubDate><description><![CDATA[本课时我们主要讲解 final 的三种用法。



final 的作用
final 是 Java 中的一个关键字，简而言之，final 的作用意味着“这是无法改变的”。不过由于 final 关键字一共有三种用法，它可以用来修饰变量、方法或者类，而且在修饰不同的地方时，效果、含义和侧重点也会有所不同，所以我们需要把这三种情况分开介绍。

我们先来看一下 final 修饰变量的情况。

final 修饰变量


作用
关键字 final 修饰变量的作用是很明确的，那就是意味着这个变量一旦被赋值就不能被修改了，.]]></description><category></category></item><item><title><![CDATA[Java多线程学习四十二：有哪些解决死锁问题的策略和哲学家就餐问题]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115644890</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115644890</guid><author>zhanghai412</author><pubDate>Mon, 12 Apr 2021 22:30:46 +0800</pubDate><description><![CDATA[线上发生死锁应该怎么办


如果线上环境发生了死锁，那么其实不良后果就已经造成了，修复死锁的最好时机在于“防患于未然”，而不是事后补救。就好比发生火灾时，一旦着了大火，想要不造成损失去扑灭几乎已经不可能了。死锁也是一样的，如果线上发生死锁问题，为了尽快减小损失，最好的办法是保存 JVM 信息、日志等“案发现场”的数据，然后立刻重启服务，来尝试修复死锁。为什么说重启服务能解决这个问题呢？因为发生死锁往往要有很多前提条件的，并且当并发度足够高的时候才有可能会发生死锁，所以重启后再次立刻发生死锁的几率并不是很大，]]></description><category></category></item><item><title><![CDATA[Java多线程学习四十一：死锁的四个条件和快速定位死锁]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115644607</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115644607</guid><author>zhanghai412</author><pubDate>Mon, 12 Apr 2021 22:23:32 +0800</pubDate><description><![CDATA[发生死锁的 4 个必要条件


要想发生死锁有 4 个缺一不可的必要条件，我们一个个来看：

第 1 个叫互斥条件，它的意思是每个资源每次只能被一个线程（或进程，下同）使用，为什么资源不能同时被多个线程或进程使用呢？这是因为如果每个人都可以拿到想要的资源，那就不需要等待，所以是不可能发生死锁的。

第 2 个是请求与保持条件，它是指当一个线程因请求资源而阻塞时，则需对已获得的资源保持不放。如果在请求资源时阻塞了，并且会自动释放手中资源（例如锁）的话，那别人自然就能拿到我刚才释放的资源，也就不会形成死锁...]]></description><category></category></item><item><title><![CDATA[Java多线程学习四十：如何写一个必然死锁的例子]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115606220</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115606220</guid><author>zhanghai412</author><pubDate>Sun, 11 Apr 2021 20:55:09 +0800</pubDate><description><![CDATA[死锁是什么？有什么危害?
什么是死锁
发生在并发中

首先你要知道，死锁一定发生在并发场景中。我们为了保证线程安全，有时会给程序使用各种能保证并发安全的工具，尤其是锁，但是如果在使用过程中处理不得当，就有可能会导致发生死锁的情况。

互不相让

死锁是一种状态，当两个（或多个）线程（或进程）相互持有对方所需要的资源，却又都不主动释放自己手中所持有的资源，导致大家都获取不到自己想要的资源，所有相关的线程（或进程）都无法继续往下执行，在未改变这种状态之前都不能向前推进，我们就把这种状态称为死锁状态，认为它们发生]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十九：CAS 有什么缺点？]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115605938</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115605938</guid><author>zhanghai412</author><pubDate>Sun, 11 Apr 2021 20:43:04 +0800</pubDate><description><![CDATA[CAS 有哪几个主要的缺点。



首先，CAS 最大的缺点就是 ABA 问题。

决定 CAS 是否进行 swap 的判断标准是“当前的值和预期的值是否一致”，如果一致，就认为在此期间这个数值没有发生过变动，这在大多数情况下是没有问题的。

但是在有的业务场景下，我们想确切知道从上一次看到这个值以来到现在，这个值是否发生过变化。例如，这个值假设从 A 变成了 B，再由 B 变回了 A，此时，我们不仅认为它发生了变化，并且会认为它变化了两次。

在这种场景下，我们使用 CAS，就看不到这两次的变化，因为仅.]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十八：你知道什么是 CAS 吗]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115605522</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115605522</guid><author>zhanghai412</author><pubDate>Sun, 11 Apr 2021 20:29:29 +0800</pubDate><description><![CDATA[CAS 简介


CAS 其实是我们面试中的常客，因为它是原子类的底层原理，同时也是乐观锁的原理，所以当你去面试的时候，经常会遇到这样的问题“你知道哪些类型的锁”？你可能会回答“悲观锁和乐观锁”，那么下一个问题很有可能是问乐观锁的原理，也就是和 CAS 相关的问题，当然也有可能会继续深入问你 CAS 的应用场景或者是缺点等问题。在本课时和接下来的这两个课时里，我将带领你学习如何回答这些问题。

首先我们来看一下 CAS 是什么，它的英文全称是 Compare-And-Swap，中文叫做“比较并交换”，它是一]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十七：volatile 的作用是什么？与 synchronized 有什么异同]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115585585</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115585585</guid><author>zhanghai412</author><pubDate>Sat, 10 Apr 2021 22:48:48 +0800</pubDate><description><![CDATA[volatile 是什么


首先我们就来介绍一下 volatile，它是 Java 中的一个关键字，是一种同步机制。当某个变量是共享变量，且这个变量是被 volatile 修饰的，那么在修改了这个变量的值之后，再读取该变量的值时，可以保证获取到的是修改后的最新的值，而不是过期的值。

相比于 synchronized 或者 Lock，volatile 是更轻量的，因为使用 volatile 不会发生上下文切换等开销很大的情况，不会让线程阻塞。但正是由于它的开销相对比较小，所以它的效果，也就是能力，相对也小]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十六：主内存和工作内存的关系]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115548832</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115548832</guid><author>zhanghai412</author><pubDate>Fri, 09 Apr 2021 14:10:27 +0800</pubDate><description><![CDATA[CPU 有多级缓存，导致读的数据过期


由于 CPU 的处理速度很快，相比之下，内存的速度就显得很慢，所以为了提高 CPU 的整体运行效率，减少空闲时间，在 CPU 和内存之间会有 cache 层，也就是缓存层的存在。虽然缓存的容量比内存小，但是缓存的速度却比内存的速度要快得多，其中 L1 缓存的速度仅次于寄存器的速度。结构示意图如下所示：



在图中，从下往上分别是内存，L3 缓存、L2 缓存、L1 缓存，寄存器，然后最上层是 CPU 的 4个核心。从内存，到 L3 缓存，再到 L2 和 L1 缓存，]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十六：Java内存结构与Java内存模型的区别]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115532641</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115532641</guid><author>zhanghai412</author><pubDate>Thu, 08 Apr 2021 22:27:03 +0800</pubDate><description><![CDATA[本课时我们主要介绍什么是 Java 内存模型？

如果你想了解 Java 并发的底层原理，那么 Java 内存模型的知识非常重要，同时也是一个分水岭，可以区分出我们是仅停留在如何使用并发工具，还是能更进一步，知其所以然。

VM 内存结构VS Java 内存模型

Java 作为一种面向对象的语言，有很多概念，从名称上看起来比较相似，比如 JVM 内存结构、Java 内存模型，这是两个截然不同的概念，但是很容易混淆。网络上也有不少讲 Java 内存模型的文章，其实写的是 JVM 内存结构。

所以我们就先.]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十五： CyclicBarrier 和 CountDownLatch 有什么不同]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115532057</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115532057</guid><author>zhanghai412</author><pubDate>Thu, 08 Apr 2021 21:44:49 +0800</pubDate><description><![CDATA[CyclicBarrier 和 CountDownLatch 有什么不同？



CyclicBarrier作用


CyclicBarrier 和 CountDownLatch 确实有一定的相似性，它们都能阻塞一个或者一组线程，直到某种预定的条件达到之后，这些之前在等待的线程才会统一出发，继续向下执行。正因为它们有这个相似点，你可能会认为它们的作用是完全一样的，其实并不是。

CyclicBarrier 可以构造出一个集结点，当某一个线程执行 await() 的时候，它就会到这个集结点开始等待，等待...]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十四：使用 Future 有哪些注意点？Future 产生新的线程了吗]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115519042</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115519042</guid><author>zhanghai412</author><pubDate>Thu, 08 Apr 2021 14:25:41 +0800</pubDate><description><![CDATA[Future 的注意点

1. 当 for 循环批量获取 Future 的结果时容易 block，get 方法调用时应使用 timeout 限制



对于 Future 而言，第一个注意点就是，当 for 循环批量获取 Future 的结果时容易 block，在调用 get 方法时，应该使用 timeout 来限制。

下面我们具体看看这是一个什么情况。

首先，假设一共有四个任务需要执行，我们都把它放到线程池中，然后它获取的时候是按照从 1 到 4 的顺序，也就是执行 get() 方法来获取的，代码如.]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十三：Future 的主要功能是什么？]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115497284</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115497284</guid><author>zhanghai412</author><pubDate>Wed, 07 Apr 2021 22:02:31 +0800</pubDate><description><![CDATA[Future 类


Future 的作用Future 最主要的作用是，比如当做一定运算的时候，运算过程可能比较耗时，有时会去查数据库，或是繁重的计算，比如压缩、加密等，在这种情况下，如果我们一直在原地等待方法返回，显然是不明智的，整体程序的运行效率会大大降低。我们可以把运算的过程放到子线程去执行，再通过 Future 去控制子线程执行的计算过程，最后获取到计算结果。这样一来就可以把整个程序的运行效率提高，是一种异步的思想。

Callable 和 Future 的关系


接下来我们介绍下 Callabl]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十二：Callable 和 Runnable 的不同？]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115496831</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115496831</guid><author>zhanghai412</author><pubDate>Wed, 07 Apr 2021 21:42:58 +0800</pubDate><description><![CDATA[为什么需要 Callable？Runnable 的缺陷


先来看一下，为什么需要 Callable？要想回答这个问题，我们先来看看现有的 Runnable 有哪些缺陷？

不能返回一个返回值


第一个缺陷，对于 Runnable 而言，它不能返回一个返回值，虽然可以利用其他的一些办法，比如在 Runnable 方法中写入日志文件或者修改某个共享的对象的办法，来达到保存线程执行结果的目的，但这种解决问题的行为千曲百折，属于曲线救国，效率着实不高。

实际上，在很多情况下执行一个子线程时，我们都希望能...]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十一：ThreadLocal 是用来解决共享资源的多线程访问的问题吗？]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115422180</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115422180</guid><author>zhanghai412</author><pubDate>Sat, 03 Apr 2021 22:59:10 +0800</pubDate><description><![CDATA[ThreadLocal 是不是用来解决共享资源的多线程访问的。

这是一个常见的面试问题，如果被问到了 ThreadLocal，则有可能在你介绍完它的作用、注意点等内容之后，再问你：ThreadLocal 是不是用来解决共享资源的多线程访问的呢？假如遇到了这样的问题，其思路一定要清晰。这里我给出一个参考答案。

ThreadLocal 并不是用来解决共享资源问题的。虽然 ThreadLocal 确实可以用于解决多线程情况下的线程安全问题，但其资源并不是共享的，而是每个线程独享的。所以这道题其实是有一定陷阱成]]></description><category></category></item><item><title><![CDATA[Java多线程学习三十：ThreadLocal 适合用在哪些实际生产的场景中]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115385256</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115385256</guid><author>zhanghai412</author><pubDate>Thu, 01 Apr 2021 21:44:18 +0800</pubDate><description><![CDATA[我们在学习一个工具之前，首先应该知道这个工具的作用，能带来哪些好处，而不是一上来就闷头进入工具的 API、用法等，否则就算我们把某个工具的用法学会了，也不知道应该在什么场景下使用。所以，我们先来看看究竟哪些场景下需要用到 ThreadLocal。

在通常的业务开发中，ThreadLocal 有两种典型的使用场景。

场景1，ThreadLocal 用作保存每个线程独享的对象，为每个线程都创建一个副本，这样每个线程都可以修改自己所拥有的副本, 而不会影响其他线程的副本，确保了线程安全。

场景2，Threa]]></description><category></category></item><item><title><![CDATA[Java多线程学习二十九：AtomicInteger（原子类） 和 synchronized 的异同点？]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115271964</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115271964</guid><author>zhanghai412</author><pubDate>Sat, 27 Mar 2021 21:29:49 +0800</pubDate><description><![CDATA[原子类和 synchronized 关键字都可以用来保证线程安全，在本课时中，我们首先分别用原子类和 synchronized 关键字来解决一个经典的线程安全问题，给出具体的代码对比，然后再分析它们背后的区别。

代码对比
首先，原始的线程不安全的情况的代码如下所示：

复制代码
public class Lesson42 implements Runnable {

  static int value = 0;

  public static void main(String[] args) ...]]></description><category></category></item><item><title><![CDATA[Java多线程学习二十八：原子类和 volatile 有什么异同？]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115101385</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115101385</guid><author>zhanghai412</author><pubDate>Mon, 22 Mar 2021 22:11:46 +0800</pubDate><description><![CDATA[原子类和 volatile 有什么异同



案例说明 volatile 和原子类的异同

我们首先看一个案例。如图所示，我们有两个线程。



在图中左上角可以看出，有一个公共的 boolean flag 标记位，最开始赋值为 true，然后线程 2 会进入一个 while 循环，并且根据这个 flag 也就是标记位的值来决定是否继续执行或着退出。

最开始由于 flag 的值是 true，所以首先会在这里执行一定时期的循环。然后假设在某一时刻，线程 1 把这个 flag 的值改为 false 了，它所.]]></description><category></category></item><item><title><![CDATA[Java多线程学习二十七：AtomicInteger 在高并发下性能不好，如何解决？为什么？]]></title><link>https://blog.youkuaiyun.com/zhanghai412/article/details/115058284</link><guid>https://blog.youkuaiyun.com/zhanghai412/article/details/115058284</guid><author>zhanghai412</author><pubDate>Sun, 21 Mar 2021 22:53:33 +0800</pubDate><description><![CDATA[AtomicInteger 在高并发下性能不好，如何解决？以及为什么会出现这种情况？



我们知道在JDK1.5 中新增了并发情况下使用的 Integer/Long所对应的原子类 AtomicInteger 和 AtomicLong。

在并发的场景下，如果我们需要实现计数器，可以利用 AtomicInteger 和 AtomicLong，这样一来，就可以避免加锁和复杂的代码逻辑，有了它们之后，我们只需要执行对应的封装好的方法，例如对这两个变量进行原子的增操作或原子的减操作，就可以满足大部分业务场景...]]></description><category></category></item></channel></rss>