Java
文章平均质量分 73
抠脚的大灰狼
这个作者很懒,什么都没留下…
展开
-
重学Java并发 - 手写并发工具类
最近再重学Java多线程的内容,Java中线程的同步基本是靠两种方式,一是Object自带的Monitor机制,通过Object上的wait/notify实现的等待/通知模式;二是JUC并发包下的Lock系列API,底层是通过LockSupport的park/unpark来实现的等待通知(park和unpark是native方法,由JVM实现,在Linux下是借助pthread_cond_wait和pthread_cond_signal实现)现使用Object的wait/notify机制,自实现一个简易的原创 2022-04-20 16:57:34 · 748 阅读 · 0 评论 -
Java使用String作为同步锁的问题
由于String会被存储到常量池中,我们知道,一般不会使用String来作为同步锁,从两方面考虑我们用String作为锁,并希望它能像Object一样,不同变量加锁互不影响。然而,有时2个String对象可能指向常量池中同一个字符串,导致其加锁互相影响。一个例子如下,若在2个类中,使用了字符串字面量赋值的方式声明2个String对象,并用synchronized关键字对两个String对象分别加锁,由于字符串常量池,2个String对象中的字符串对象指向的是常量池中同一个内存区域,故2个加锁方法会彼此原创 2020-10-09 16:59:09 · 4544 阅读 · 0 评论 -
TransmittableThreadLocal的简单使用 + 手写源码
文章目录使用方法原理手写源码之前有一篇文章谈到链路追踪场景下,需要在异步线程之间,实现跨线程的ThreadLocal传递, 简单场景可以用InheritableThreadLocal,但ITL在线程池化场景下不适用,因为ITL是在子线程初始化时,拷贝了父线程的ThreadLocal,但池化场景,子线程是会被多次复用的,但ITL只能在子线程第一次创建时,传递ThreadLocal,之后的复用都无法重新设置ThreadLocal。于是TransmittableThreadLocal出现了,可以解决Thread原创 2020-06-04 13:25:06 · 1591 阅读 · 0 评论 -
DelayQueue 最简单的使用与原理
文章目录基本使用基本原理变量操作基本使用实现Delayed接口import java.time.Instant;import java.time.LocalDateTime;import java.time.ZoneId;import java.time.format.DateTimeFormatter;import java.util.concurrent.Delayed;import java.util.concurrent.TimeUnit;public class Delay原创 2020-06-03 23:57:52 · 288 阅读 · 0 评论 -
JavaWeb基石之——Servlet
最近一段时间,老是觉得学不爽,焦虑而急躁。归根到底,是没有一个较好的学习路径。像是还没学会走,就想飞一样。学习,还是要按照一定的路径,一步一步来。才能学的扎实,走的稳重。以实践为指导,输出倒逼输入,才能学的更有意义,也让知识消化的更彻底。而不是一味地为了学习而学习。就像很多人一上来就想着如何去阅读Spring源码,为什么呢?因为这样能在面试时让面试官高看自己一眼呀,很多公司现在招聘都会要求面试者阅读过什么什么源码。源码阅读没有错,也是一个想要在技术上深耕的人的必经之路。只是它应该往后放,学习不应该这么浮原创 2020-05-09 11:56:10 · 467 阅读 · 1 评论 -
战五渣手撕LRU
手撕LRU背景介绍我们从一个程序的运行过程说起。在运行之前,QQ,就是一堆文件,它静静地躺在磁盘的某个角落。当我们双击QQ图标时,操作系统老大就会找到磁盘中QQ的安装目录,并将其中的文件装载到内存,然后安排CPU阿甘进行相关的运算,小企鹅就跑起来了。我们知道磁盘的空间非常大,内存与之相比,是非常小的。所以并不是一次性把QQ的所有文件加载到内存,那样的话,电脑根本不能同时运行多个程序(就算一...原创 2020-04-18 15:53:20 · 374 阅读 · 1 评论 -
拨开HashMap的隐秘森林
之前看过一次HashMap源码,忒难看。直接怼源码容易迷失在黑暗的森林中,开debug跟流程又不能一一睹其完整的芳容。于是尝试着先按自己的思路手撕一版简单的HashMap,再拿来和jdk的HashMap做比较,以此来拨开H。按照预想,我的HashMap也采用了数组+链表的形式,它包含了如下的成员变量:private Node<K,V>[] tab; //用来存放Key-Value对...原创 2020-04-19 16:03:02 · 318 阅读 · 0 评论 -
基于Java Swing的迷宫随机生成 + 自动寻路 demo(附源码)
《算法 小灰》 快看完了。最近学到A星寻路算法,觉得颇有意思,于是百度Google,花了2天时间捣鼓出一个基于Swing的可视化迷宫生成和寻路demo。在此做个记录~小demo使用的迷宫生成算法是DFS,寻路用的A星。这样以来,生成的迷宫任意2个格子之间都可达,且走出迷宫的最短路径是唯一的。参考链接:Swing快速入门教程迷宫生成算法最终效果:...原创 2020-02-17 00:48:53 · 1191 阅读 · 0 评论 -
重温计数排序
一开始想,对数组进行排序,肯定是要比较的呀,不比较怎么知道大小。直到遇见了计数排序,桶排序,基数排序。真是感叹人类的牛逼。居然还能这样?话不多说,下面开始重温计数排序基本思路:先从简单的例子说起。如果给定一个大小为10的数组,并且知道数组里的元素都在0-10的范围内。那么可以建一个长度为11的数组(初始值为0)用于计数。再遍历原始数组,以数组元素的值,作为下标,定位到计数数组中的某个位置,...原创 2020-01-13 23:31:54 · 193 阅读 · 0 评论 -
重温堆排序及二叉堆的应用场景
堆排序算法基本思路:将待排序数组,看成是一个数组形式的完全二叉树(节点在层序遍历中的顺序,即是元素在数组中的顺序),先对数组进行调整,使其成为一个大根堆,或者小根堆。调整完后,每次将堆顶元素(数组首元素),与最后一个元素交换,然后把最后一个元素从堆中删除(逻辑上删除),将剩余元素进行调整,形成一个新的堆,再把堆顶元素和堆尾元素交换,把堆尾元素删除,再调整剩余元素… 一直到堆为空,即得到一...原创 2020-01-11 00:03:42 · 677 阅读 · 0 评论 -
重温快速排序(递归与非递归实现)
算法基本过程简单讲,就是分治。选一个基准元素,将序列分割成两部分,使得左边的都比基准小,右边的都比基准大。此时基准元素位置确定了,左右两侧也相对有序。再把左右子序列看成独立的序列,选基准,分割成左边小,右边大的两部分,一直分到无法再划分下去。快排快在哪?相比于冒泡排序每一轮只把一个元素冒泡到序列的一端。快排虽然每一轮也只能确定一个元素的最终位置,但它用分治的思路,每一轮使得左右两侧变...原创 2020-01-08 21:48:37 · 213 阅读 · 0 评论 -
重温冒泡排序(优化思路+鸡尾酒排序)
第一版冒泡排序:public void bubbleSort(int[] arr){ //每次冒泡一个最大的上去 for (int i = arr.length - 1; i > 0; i--){ for (int j = 0; j < i; j++){ if (arr[j] > arr[j...原创 2019-12-30 23:18:42 · 219 阅读 · 0 评论 -
Unicode,UTF-8,UTF-16傻傻分不清?一文看懂
文章目录ASCIIUnicodeUTF-8UTF-16UTF-32ASCII美国人制定的一套字符集,描述英语中的字符和8位二进制数(1字节)的对应关系,这被称为 ASCII 码。ASCII码共定义了128个字符,使用了8位二进制数中的7位,最高位统一规定为0。128个字符对英语来说足够了,但对于其他语言来说是不够的。大家在0~127号字符上达成了一致,但对于128~255号字符,不同国家有不同...原创 2019-06-24 13:06:02 · 953 阅读 · 0 评论 -
一文看懂正则表达式
Java 正则JDK内置的正则表达式引擎:java.util.regex用字符串来描述规则,用于匹配字符串的一种机制最简单的代码示例String input = "1926";String regex = "19\\d{2}";System.out.println(input.matches(regex)); //true//注意String 的matches方法,参数中的reg字...原创 2019-06-24 22:35:29 · 409 阅读 · 0 评论 -
并发与volatile总结
并发基本问题要想并发程序正确地执行,必须要保证原子性,可见性,以及有序性原子性即一个操作或多个操作,要么全部执行成功,且执行的过程不被打断,要么就不执行。经典的例子是转账问题:从A账户中扣100元,再在B账户中加100元。两个操作要么全部执行成功,要么不执行,这就是操作的原子性可见性即当多个线程访问同一变量时,若一个线程修改了该变量的值,其他的线程能够立即看到修改后的值,如/...原创 2019-06-29 23:49:58 · 265 阅读 · 0 评论 -
《看不懂你打我系列》之 —— 极简JDK动态代理
大白话来讲,代理就是一个类代替另一个类去做一些事,在现实生活中好比媒婆代理你,去给你找对象,或者在你科学上网时,876服务器代理你的电脑去为你打开世界的大门。归纳起来,代理的过程无非就两点:谁需要被代理?代理他的人需要为他做些什么?用稍微专业一些的话来说,只需要明确2点:1.目标类(被代理类) 2.增强(代理类需要做的事)。代理又分为静态代理和动态代理,静态代理是在编译期就确定了目标类,直接编...原创 2019-07-21 11:20:46 · 222 阅读 · 0 评论 -
ThreadLocal源码解析
ThreadLocal<T>实例字段threadLocalHashCodeprivate final int threadLocalHashCode = nextHashCode();每个ThreadLocal实例的hashCode。用于将ThreadLocal变量插入到线程中的一个哈希表中(线程的ThreadLocalMap字段)实例方法protected T...原创 2019-07-21 11:49:20 · 219 阅读 · 0 评论 -
HashMap源码浅析(一)
HashMap<T>java.util.HashMap其内部的冲突解决方案采用的是拉链法,故HashMap的结构表现为数组+链表插入时,先根据Key的hashCode,定位到待插入的地址,若待插入的地址为空,则直接插入;若待插入的地址不为空,说明发生冲突,则用拉链法,将元素插入到该地址的链表中。拉链法会导致链表过深,而造成性能下降的问题,HashMap中,当链表长度过长时,会选...原创 2019-07-22 23:34:30 · 295 阅读 · 0 评论 -
极简JAVA 注解
自定义注解使用@interface定义注解可定义多个参数和默认值,核心参数推荐使用value必须通过一些元注解来修饰自定义注解,@Target指定注解的应用范围设置@Retention设置注解的作用范围(一般设置为RUNTIME)@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.M...原创 2019-08-06 23:29:17 · 283 阅读 · 0 评论 -
《看不懂你打我系列》之 —— 极简ArrayList
要点基本实现扩容机制数组拷贝基本实现内部使用了Object [] elementData 来存储元素,这是一个缓冲数组,其末尾一般会余留一些空位给待插入的元素。注意到elementData是被transient关键字修饰的,被transient修饰的字段,不会参与对象的序列化。对ArrayList进行序列化,我们调用其实例方法writeObject(),其会依次序列化elemen...原创 2019-10-10 12:30:04 · 219 阅读 · 0 评论 -
关于算术移位,逻辑移位的一些思考
今天研究编码方式时,遇见了大小端问题,准备用IDEA测一下本地系统是大端还是小端模式时,又遇到了移位操作,重新温习了一下,特此记录。注:以下讨论的内容,皆以补码作为数据表示形式,实际计算机系统中也以补码来存储数据。(为什么要强调以补码为前提呢?戳这里)首先从理论的角度来说,关于算术移位和逻辑移位通俗的理解如下:逻辑移位:仅做最纯粹的移位操作,不考虑其他情况算术移位:移位时需要做算术方...原创 2019-06-24 00:00:02 · 2483 阅读 · 2 评论