同步容器(使用的是synchronized,并且不一定是百分百安全)
本篇续 -- 线程之间的通信 ,介绍java提供的并发集合,既然正确的使用wait和notify比较困难,java平台为我们提供了更高级的并发容器来替代
一. Vector&ArrayList
Vector虽然它的set和get方法都被Synchronized修饰,但是开启两条线程并发访问,一条线程拼命往里写,另一台循环往移除,这样并发访问不一定是百分百的线程安全的,很可能出现数组越界异常,而且现在基本已经不适用它了,它基本被ArrayList替代掉了
ArrayList是线程不安全的
将ArrayList转换成线程安全的
ArrayList al = new ArrayList();
Connections.syncchronizedList(al);
Map
将HashMap转换成线程安全的
HashMap map = new HashMap<>();
Map map1 = Collections.synchronizedMap(map);
并发容器J.U.C
一. 并发List--CopyOnWriteArrayList
它是ArrayList 的一个线程安全的变体,其中所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。
我们着重的关注点是啥呢? 可能会出现线程安全性问题的方法 set() add() remove() ,
基本的使用;
同样实现了List接口,那么其实它的使用和ArrayList完全一样的,只是内部的实现不一样
实现原理
分析add方法
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock; //获取锁ReentrantLock
lock.lock();
try {
Object[] elements = getArray(); // 获取CopyOnWriteArrayList内部维护的数组
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1); // 复制该数组到 newElements数组里面 并扩容
newElements[len] = e; //在数组最后添加新的元素
setArray(newElements); //让替换掉原来的数组
return true; //添加成功
} finally {
lock.unlock();
}
}
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
return get(getArray(), index);
}
可以看到,其实类似读写分离, add()可能会出现线程安全问题,因此给它一把锁,get()不会出现线程安全性问题,因此没有锁,如果非要给get也加上锁,那么在add的时候,就不能get了,因为它拿不到锁对象
之所以说是读写分离,读read,读取的原数组,add写的时候,其实不是往原array里面写,而是分如下几步
加锁
拷贝原数组,创建新的数组
添加新的元素
新数组替换原数组
释放锁
分析remove方法
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices). Returns the element that was removed from the list.
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
E oldValue = get(elements, index);
int numMoved = len - index - 1;
if (numMoved == 0) //移除最后一个
setArray(Arrays.copyOf(elements, len - 1));
else { // 移除其它的,当前元素后面的需要往前移动
Object[] newElements = new Object[len - 1];
System.arraycopy(elements, 0, newElements, 0, index);
System.arraycopy(elements, index + 1, newElements, index,
numMoved);
setArray(newElements);
}
return oldValue; // 移除谁,返回谁
} finally {
lock.unlock();
}
}
总结一下
假如说多线程并发的应用中,绝大部分都是读操作 ,那么,CopyOnWriteArrayList效率明显高 ,因为他是读写分离,读没有锁,是在原数组上进行的,写也是线程安全的(加了lock),其中有一点就是它虽然能保证数据的最终是同步的,但是却保证不了实时同步性
假如说绝大部分操作是写操作 ,可以看到,还是挺吃内存的,数组过大,他的效率可能就不一定比同步容器高,在不知道往里面存储多少数据的情况下,慎用.在高并发的互联网环境下这种操作分分钟就导致故障
二. 并发Set
和List步调一致的是,java平台为set集合提供了CopyOnWriteArraySet ,它实现了set接口,底层完全依赖CopyOnWriteArrayList 因此,它的特性和CopyOnWriteArrayList一致,同样在读多写少 的高并发环境下,拥有很高的效率
同样,在写多读少 的高并发环境下,我们可以考虑下面的转换
Set set = Collections.synchronizedSet(new HashSet<>());
三. 并发Map
同样可以使用Collections获取到一个同步Map,但是这个Map的性能依然不是最优的
Collections.synchronizedMap();
jdk1.8中ConcurrentHashMap内部抛弃了锁分离而使用红黑树实现
四. 并发Queue
在并发队列上,java提供了两套实现,一个是ConcurrentLinkedQueue的非阻塞型的队列,另一个是BlockingQueue接口,阻塞队列,同样他们继承了Queue接口
1 . ConcurrentLinkQueue 非阻塞队列
保证了在高并发的情况下,对link底层维护的链表的增删改各个节点的安全性
实现原理
它通过无锁的方法,底层使用的是UNSAFE实现(保证线程的安全性) 入队offer
/**
* Inserts the specified element at the tail of this queue.
* As the queue is unbounded, this method will never return {@code false}.
*
* @return {@code true} (as specified by {@link Queue#offer})
* @throws NullPointerException if the specified element is null
*/
public boolean offer(E e) {
checkNotNull(e); // 检查新添加的内容是否为空
final Node newNode = new Node(e); // 将其放入新节点
for (Node t = tail, p = t;;) { // 整个一个for循环, 循环遍历链表,寻找适当的位置,插入新节点
Node q = p.next;
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
// Successful CAS is the linearization point
// for e to become an element of this queue,
// and for newNode to become "live".
if (p != t) // hop two nodes at a time
casTail(t, newNode); // Failure is OK. //可以看到,在这种会出现线程安全性问题的地方,使用的是cas进行操作,保证了线程的安全性
return true;
}
// Lost CAS race to another thread; re-read next
}
else if (p == q)
// We have fallen off list. If tail is unchanged, it
// will also be off-list, in which case we need to
// jump to head, from which all live nodes are always
// reachable. Else the new tail is a better bet.
p = (t != (t = tail)) ? t : head;
else
// Check for tail updates after two hops.
p = (p != t && t != (t = tail)) ? t : q;
}
}
// 可以看到,casXXX 底层使用的是UNSAFE实现(保证线程的安全性)
private boolean casTail(Node cmp, Node val) {
return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
}
private boolean casHead(Node cmp, Node val) {
return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
}
图解节点的添加过程,在001文件中
出队
public E poll() {
restartFromHead:
for (;;) {
for (Node h = head, p = h, q;;) {
E item = p.item;
if (item != null && p.casItem(item, null)) {
// Successful CAS is the linearization point
// for item to be removed from this queue.
if (p != h) // hop two nodes at a time
updateHead(h, ((q = p.next) != null) ? q : p);
return item;
}
else if ((q = p.next) == null) {
updateHead(h, p);
return null;
}
else if (p == q)
continue restartFromHead;
else
p = q;
}
}
阻塞队列BlockingQueue
java.util.concurrent 接口 BlockingQueue 类型参数: E - 在此 collection 中保持的元素类型 所有超级接口: Collection , Iterable , Queue 所有已知子接口: BlockingDeque 所有已知实现类: ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue
主要应用场景: 生产者和消费者模式
BlockingQueue是一个接口,因此我们学习ArrayBlockingQueue ,它的底层维护着一个数组的阻塞队列
一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。
此类支持对等待的生产者线程和使用者线程进行排序的可选公平策略。默认情况下,不保证是这种排序。然而,通过将公平性 (fairness) 设置为 true 而构造的队列允许按照 FIFO 顺序访问线程。公平性通常会降低吞吐量,但也减少了可变性和避免了“不平衡性”。
此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选 方法。
既然叫阻塞队列,也就是说,他支持在多线程的条件下,多线程并发添加移除数组的元素,会被阻塞等待,而不会抛出空值异常或者报错,且数组的长度不可变
两种情况发生阻塞
队列满的时候,进行入队操作,也就是说,队列满了,但是有一个线程往队列里面put的时候,他会被阻塞,除非有别的线程做了take的操作
队列为空,进行出队操作
put
将指定元素插入此队列中,将等待可用的空间(如果有必要)。
take
获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。
可以直接使用它,实现消费者生产者模式,他的底层是用Condition ReentrantLock实现的--,方法被lock()和unlock()锁住, 数组满就await , 出队后signal
add
将指定元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException
remove
从此队列中移除指定元素的单个实例(如果存在)。同样会抛异常
offer
将指定元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false。
poll
获取并移除此队列的头部,在指定的等待时间前等待可用的元素(如果有必要)。没有元素,返回null
五 .并发Deque
jdk1.6开始java提供的双端队列Deque(Double Ended Queue) 允许在队列的头部或者尾部进行入队或者出队的操作. 他是是实现类:
ArrayDeque
使用数组实现了双端队列,拥有更好的随机访问性,但是当队列的增大时,他需要重新分配内存,然后进行数组的复制
LinkedList
LinkedBlockingDeque
> 线程安全,但是它没有进行读写分离,也就说,同一时间,只允许一条线程对其操作,因此在并发中,它的性能,远远底于ConcurrentLinkQueue 参考 博文 你不就像风一样
你可能感兴趣的:(多线程六 同步容器&并发容器)
ChatTTS-ui模型概述、安装及使用方法说明
醉心编码
人工智能基础 技术类 脚本基础 TTS 大模型 人工智能
ChatTTS-ui模型概述、安装及使用方法说明一、ChatTTS-ui模型概述二、ChatTTS-ui的技术优势三、ChatTTS-ui的安装与配置1.安装Python和Git环境2.下载ChatTTS-ui源码3.创建并激活虚拟环境4.安装依赖5.启动应用四、ChatTTS-ui的高级功能1.API调用2.音色自定义3.细粒度控制4.GPU加速五、ChatTTS-ui的应用场景六、ChatTT
当Docker网络抽风时,如何优雅地摔键盘(并悄悄修好它)
以琦琦为中心
docker 网络 容器
title:“️当Docker网络抽风时,如何优雅地摔键盘(并悄悄修好它)”author:“Cjs”date:“2025-2-23”当你的容器们开始玩"失联游戏"时…ERROR:Couldnotconnecttodatabase容器A:"嘿兄弟你在哪?"容器B:"我在192.168.9.2啊!"宿主机:"你们说的这个ip...我根本不认识啊!"经典崩溃现场:容器间突然开始"量子通信"(时通时不通)
Android异步任务与多线程
2401_89224638
android
ANR的根本原因是:应用未在规定的时间内处理AMS指定的任务才会ANR。另外,人眼可以分辨的时间的160毫秒,超过这个时间就可以感到卡顿,所以要控制好这个时间。1.2.3、事件处理原则事件处理的原则:所有可能耗时的操作都放到其他线程去处理。Android中的main线程的事件处理不能太耗时,否则后续的事件无法在5秒内得到响应,就会弹出ANR对话框。那么哪些方法会在main线程执行呢?1)Activ
Docker内存芭蕾:优雅调整容器内存的极限艺术
以琦琦为中心
docker 容器 运维
title:“Docker内存芭蕾:优雅调整容器内存的极限艺术”author:“Cjs”date:“2025-2-23”emoji:“”当你的容器变成内存吸血鬼时…完美内存编排示范智能内存管家脚本#!/bin/bash#memory_balancer_v3.sh#定义容器列表和对应的内存分配比例(总可用内存的百分比)containers=("container-1""container-2""co
使用exec模式与shell模式,执行ENTRYPOINT和CMD的区别
yyytucj
运维
在Docker容器的世界里,ENTRYPOINT与CMD指令负责启动容器时运行的默认程序及传递给该程序的默认参数。它们的行为差异,尤其是结合exec与shell两种执行模式时,为容器的启动过程增添了灵活性与可控性。下面将详细探讨这两种模式下,ENTRYPOINT与CMD的不同表现形式及其影响。执行模式概览Shell模式:默认模式,会在/bin/sh中执行命令,允许使用shell特性如管道、重定向等
nginx主要功能及其原理介绍
大名-
在学习nginx之前首先了解一下什么是同步与异步,什么是阻塞与非阻塞。一、同步与异步同步与异步的重点在消息通知的方式上,也就是调用结果的通知方式不同。同步:当一个同步调用发出去后,调用者要一直等待调用的结果通知后,才能进行后续的操作。异步:当一个异步调用发出去后,调用者不必一直等待调用结果的返回,异步调用,要想获得结果,一般有两种方式:1.主动轮询异步调用的结果;2.被调用方通过callback(
飞天侠:用 aioredis 加速你的 Redis 操作
星际编程喵
Python探索之旅 redis 数据库 缓存 python
前言如果你还在用同步方式操作Redis,你的应用可能还停留在“慢跑”阶段,而不是极速奔跑!在现代高性能应用中,响应速度至关重要,而异步操作就是那把解锁高速的钥匙。而aioredis,这款基于asyncio的Redis异步客户端,正是帮你提升性能、缩短延迟的得力助手。它能让你像开跑车一样,秒杀同步操作的瓶颈,快速处理海量请求。今天,我们就来一起揭秘这款神奇工具,看看如何通过aioredis加速你的R
Tomcat体系架构第一篇
gaochaojin
Tomcat Java Tomcat
一、Tomcat的定义Tomcat是一款开源轻量级Web应用服务器,是一款优秀的Servlet容器实现。Servlet是JavaServlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互地浏览和生成数据,生成动态Web内容。Servlet严格来讲是指Java语言实现的一个接口,一般情况下我们说的Servlet是指实现了这个Servl
在 Ubuntu 上安装 Docker 的完整指南
花千树-010
Docker ubuntu docker linux
在Ubuntu上安装Docker的完整指南Docker是一个开源的平台,可以轻松创建、部署和运行应用程序在容器中。容器允许开发者将应用程序及其所有依赖项打包到一个标准化单元中,从而确保应用在任何环境中都可以一致运行。本文将详细介绍如何在Ubuntu上安装Docker。前提条件在开始之前,请确保您的系统满足以下条件:Ubuntu版本:16.04、18.04、20.04或更高版本用户具有sudo权限安
Linux系统——Nginx常见面试题
一坨小橙子ovo
linux nginx 服务器
目录一、Nginx使用场景二、Nginx的发展历史三、Nginx没出现之前都存在过什么问题四、Nginx的优点五、正向代理和反向代理分别是什么六、Nginx限流问题七、Nginx动静分离八、什么是负载均衡九、Nginx负载均衡的策略有哪些十、Nginx多进程模型十一、为什么Nginx不使用多线程十二、Nginx高可用性十三、Nginx压缩十四、总结Nginx是一种高性能的HTTP和反向代理服务器,
Java——单例类设计模式
六七_Shmily
java java 设计模式 单例模式
在Java中,单例类(SingletonClass)是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来获取该实例。单例模式通常用于管理共享资源(如数据库连接、线程池、配置管理器等),避免重复创建对象,节省系统资源。1.单例模式的核心特点唯一实例:单例类只能有一个实例。全局访问点:通过静态方法提供全局访问。私有构造器:防止外部通过new关键字创建实例。线程安全:确保在多线程环境下也能
常用设计模式(embeded Qt)
m0_55576290
Balance 设计模式 qt java
常用设计模式:观察者模式(ObserverPattern)应用场景:传感器数据更新、UI状态同步。实现方式:通过QT的信号槽机制(本质是发布-订阅模式)自动实现。例如:connect(sensor,&Sensor::dataUpdated,uiWidget,&UIWidget::updatePlot);策略模式(StrategyPattern)应用场景:动态切换动平衡算法(如影响系数法、试重法等)
linux下mysql主从配置详细教程
科技梦想家
linux mysql 运维
主库配置:确保server-id唯一,设置binlog-do-db和binlog-ignore-db适当。考虑开启gtid_mode。创建账号:创建具有复制权限的用户,并确保更新权限。从库配置:设置server-id和log-bin,并确保从库的replicate-do-db正确。同步命令:使用CHANGEMASTERTO命令,确保IP、用户和日志位置正确。检查状态:用SHOWSLAVESTATU
三甲医院等级评审八维数据分析应用(六)--数据安全与隐私保护篇
Allen_LVyingbo
数智化医院2025 数据分析 人工智能 集成学习 健康医疗
一、引言1.1研究背景与意义随着信息技术在医疗领域的深度渗透,三甲医院在日常运营中积累了海量的医疗数据,包括患者的基本信息、病历记录、诊断影像、检验结果等。这些数据成为医院开展精准医疗、优化服务流程、提升管理决策科学性的关键依据。然而,数据的大规模集中存储与频繁交互流通,使得数据安全与隐私保护面临前所未有的严峻挑战。一旦发生数据泄露事件,不仅会损害患者的个人隐私权益,引发公众对医院信任危机,还可能
Docker部署Django(三)docker-compose编排Django+Uwsgi+Nginx+MySQL
诸葛钢铁云
Docker
写在前面实际的生产环境中,我们往往需要定义数量庞大的docker容器,并且容器之间具有错综复杂的依赖联系,一个一个去手动创建容器并记录和配置这些复杂的容器关系,不仅效率低下而且容易出错,所以迫切需要一种定义容器集群编排和部署的工具,这就是docker-compose什么是docker-compose及docker-compose工具的安装Docker-compose是一个用来定义和运行复杂应用的D
利用flex来布局顶部菜单栏
学习做游戏中
css3 flex
安装vscode插件csspeek:快速定位到css定义的位置微软的livepreview替换liveserver因为这个好像不支持utf8前置css知识span标签是一个行内容器,用于标记文本的一部分,或文档的一部分。它与div非常相似,但div是块级元素,而span是行内元素。p段落标签,可设置line-height属性text-align设置块元素或者单元格框的行内内容的水平对齐。这意味着其
操作系统选择题题库
帅小柏
笔记 操作系统
B站关注帅小柏,点波关注不迷路!第一章、第二章第三章进程第四章处理机调度第五章,存储管理第六章文件第七章设备第一章、第二章1、操作系统是一种()。A、应用软件B、系统软件C、通用软件D、工具软件答案:B解析:根据操作系统的定义,它是计算机系统中最重要的系统软件。2、多道程序设计是指()。A、在分布系统中同一时刻运行多个程序B、在一台处理机上同一时刻运行多个程序C、在实时系统中并发运行多个程序D、在
Spring篇
hxung
面试学习使用 spring java 后端
Spring篇1.IOC控制反转IOC(InverseofControl:控制反转)是⼀种设计思想,就是将原本在程序中⼿动创建对象的控制权,交由Spring框架来管理。IOC在其他语⾔中也有应⽤,并⾮Spring特有。IOC容器是Spring⽤来实现IOC的载体,IOC容器实际上就是个Map(key,value),Map中存放的是各种对象。将对象之间的相互依赖关系交给IOC容器来管理,并由IOC容
c++ std::list使用笔记
JANGHIGH
C++ c++ list 笔记
c++std::list使用笔记1.包含头文件2.创建和初始化`std::list`3.添加元素4.删除元素5.访问元素6.遍历`std::list`7.容量相关操作8.其他常用操作9.示例代码总结std::list是C++标准库中的一个双向链表容器。与std::vector不同,std::list不支持随机访问,但它在任意位置插入和删除元素的操作效率更高(时间复杂度为O(1))。以下是std::
音视频封装格式:多媒体世界的“容器”与“桥梁”
码流怪侠
音视频 音视频 容器 FLV MP4 TS 视频编解码 MOV
一、音视频封装格式的核心概念音视频封装格式(容器)是一种将编码后的视频、音频、字幕等数据按规则整合的文件格式,其本质是多媒体数据容器,核心作用包含:同步多轨道数据:通过时间戳(PTS/DTS)实现音画同步。组织数据流:统一管理视频流、音频流、字幕流等,并存储元数据(如分辨率、编码参数)。兼容性与扩展性:不同封装格式支持特定编码标准和功能(如多音轨、DRM版权保护)。二、主流封装格式详解TS(Tra
PHP的数据结构一共有哪些?使用场景是什么?底层原理是什么?
快点好好学习吧
PHP php 数据结构 android
PHP的数据结构是编程中用来存储和组织数据的方式。它们就像不同的“容器”,可以用来装不同类型的东西。1.PHP的常见数据结构(1)数组(Array)定义:数组是一种可以存储多个值的容器。它可以是索引数组(用数字作为键)或关联数组(用字符串作为键)。示例:$fruits=["apple","banana","cherry"];//索引数组$person=["name"=>"Alice","age"=
cocos creator 项目总结二(战斗帧同步解析)
xzben
cocos creator 帧同步
一、帧同步原理:帧同步,指的是将游戏过程中关键的操作帧数据同步给各个客户端实现游戏同步的方案。这个原理看上去一句话很简单,但是其实内部涉及的细节却很多,影响到游戏的卡顿,同步是否完全同步等问题,接下来我一一列举我制作过程中遇到的问题和解决方案。二、客户端同步一致性问题1、逻辑驱动归一管理,这个主要是要将战斗过程的所有逻辑运算update驱动要统一管理,而不是简单的通过UI层的update分散驱动,
【可靠有效】springboot使用netty搭建TCP服务器
weixin_43833540
spring boot netty tcp
NettyNetty是一个高性能、异步事件驱动的网络应用程序框架,它提供了对并发和异步编程的抽象,使得开发网络应用程序变得更加简单和高效。在Netty中,EventLoopGroup是处理I/O操作的多线程事件循环器。在上面的示例中,我们创建了两个EventLoopGroup实例:bossGroup和workerGroup。bossGroup负责接收客户端的连接请求,并将这些连接分配给worker
【Python爬虫(45)】Python爬虫新境界:分布式与大数据框架的融合之旅
奔跑吧邓邓子
Python爬虫 python 爬虫 分布式 开发语言 大数据框架
【Python爬虫】专栏简介:本专栏是Python爬虫领域的集大成之作,共100章节。从Python基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取,还涉及数据处理与分析。无论是新手小白还是进阶开发者,都能从中汲取知识,助力掌握爬虫核心技能,开拓技术视野。目录一、大数据处理框架初印象1.1Hadoop:大数据处理的基石1.2
std::thread的同步机制
li星野
C++ c++ 学习 开发语言
在C++中,std::thread用于创建和管理线程。为了确保多个线程能正确、安全地访问共享资源,避免数据竞争和不一致问题,需要使用同步机制。互斥锁(std::mutex)原理:互斥锁是一种最基本的同步原语,用于保护共享资源。同一时间只允许一个线程访问被互斥锁保护的代码段,其他线程必须等待该线程释放锁后才能继续访问。#include#include#includestd::mutexmtx;int
《西湖绸》(仿郭敬明「蜀绣」)
后端
《西湖绸》歌词【主歌1】西子眉黛深浅入云岫(苏轼)孤山寺北云脚低(白居易)白沙堤上系兰舟半城烟雨半城绸(化用"半壕春水一城花")【副歌1】三潭月影缝着二十四桥秋(张岱/杜牧)柳浪闻莺处谁裁锦字收断桥残雪绣白蛇千年眸(白蛇传典故)雷峰斜照里金线锁重楼(张岱)【主歌2】曲院风荷穿针银鳞游(杨万里)花港观鱼衔走苏小愁(白居易/苏小小)平湖秋月晾鲛绡皱(化用"鲛人潜织"典故)六和听潮解连环锈(周密/辛弃疾
【六】Golang 运算符
张胤尘
Golang golang 开发语言 后端
欢迎来到张胤尘的技术站技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌文章目录运算符算术运算符注意事项关系运算符逻辑运算符注意事项位运算符常见操作检查特定位是否为1(检查整数的奇偶性)设置特定位为1清除特定位交换变量值快速乘除注意事项赋值运算符基本赋值运算符复合赋值运算符指针运算符注意事项优先级运算符golang中支持运算符:算术运算符、关系运算符、逻
深入解析Java线程锁机制:从原理到最佳实践
XU磊260
JAVA java
##引言在多线程编程中,线程安全是开发者面临的核心挑战之一。当多个线程并发访问共享资源时,如果没有正确的同步机制,就可能出现数据不一致、竞态条件等问题。Java提供了多种线程锁机制来保障线程安全,本文将深入探讨Java中的各种锁实现、使用场景和优化策略。一、线程锁的核心作用1.1互斥访问确保同一时刻只有一个线程可以访问临界区代码,防止并发修改导致的数据不一致。1.2可见性保证通过锁机制强制内存屏障
索引的优缺点与常见类型详解
豪宇刘
mysql sql 数据库
索引是数据库优化的核心工具,但盲目使用可能适得其反。本文将系统梳理索引的缺点、常见类型及适用场景,助你避开常见陷阱。一、索引的缺点虽然索引能加速查询,但并非“免费午餐”,需警惕以下代价:1.存储空间开销每个索引都需要额外的磁盘空间存储(B-Tree、哈希表等结构)。示例:一张1GB的表,若创建3个索引,总存储可能膨胀至2GB以上。2.写操作性能下降增删改数据时,索引需要同步更新,导致写入延迟。场景
Spring Bean 生命周期的执行流程详解
豪宇刘
java 开发语言
Spring框架以其强大的依赖注入和生命周期管理功能而闻名。理解SpringBean的生命周期对于开发者来说至关重要,因为它可以帮助我们更好地设计和优化应用,特别是在处理复杂的依赖注入和初始化逻辑时。本文将详细介绍SpringBean生命周期的五个主要阶段:创建前准备阶段、创建实例阶段、依赖注入阶段、容器缓存阶段和销毁实例阶段,并通过简单的示例帮助你更好地理解这一过程。一、SpringBean生命
java责任链模式
3213213333332132
java 责任链模式 村民告县长
责任链模式,通常就是一个请求从最低级开始往上层层的请求,当在某一层满足条件时,请求将被处理,当请求到最高层仍未满足时,则请求不会被处理。
就是一个请求在这个链条的责任范围内,会被相应的处理,如果超出链条的责任范围外,请求不会被相应的处理。
下面代码模拟这样的效果:
创建一个政府抽象类,方便所有的具体政府部门继承它。
package 责任链模式;
/**
*
linux、mysql、nginx、tomcat 性能参数优化
ronin47
一、linux 系统内核参数
/etc/sysctl.conf文件常用参数 net.core.netdev_max_backlog = 32768 #允许送到队列的数据包的最大数目
net.core.rmem_max = 8388608 #SOCKET读缓存区大小
net.core.wmem_max = 8388608 #SOCKET写缓存区大
php命令行界面
dcj3sjt126com
PHP cli
常用选项
php -v
php -i PHP安装的有关信息
php -h 访问帮助文件
php -m 列出编译到当前PHP安装的所有模块
执行一段代码
php -r 'echo "hello, world!";'
php -r 'echo "Hello, World!\n";'
php -r '$ts = filemtime("
Filter&Session
171815164
session
Filter
HttpServletRequest requ = (HttpServletRequest) req;
HttpSession session = requ.getSession();
if (session.getAttribute("admin") == null) {
PrintWriter out = res.ge
连接池与Spring,Hibernate结合
g21121
Hibernate
前几篇关于Java连接池的介绍都是基于Java应用的,而我们常用的场景是与Spring和ORM框架结合,下面就利用实例学习一下这方面的配置。
1.下载相关内容: &nb
[简单]mybatis判断数字类型
53873039oycg
mybatis
昨天同事反馈mybatis保存不了int类型的属性,一直报错,错误信息如下:
Caused by: java.lang.NumberFormatException: For input string: "null"
at sun.mis
项目启动时或者启动后ava.lang.OutOfMemoryError: PermGen space
程序员是怎么炼成的
eclipse jvm tomcat catalina.sh eclipse.ini
在启动比较大的项目时,因为存在大量的jsp页面,所以在编译的时候会生成很多的.class文件,.class文件是都会被加载到jvm的方法区中,如果要加载的class文件很多,就会出现方法区溢出异常 java.lang.OutOfMemoryError: PermGen space.
解决办法是点击eclipse里的tomcat,在
我的crm小结
aijuans
crm
各种原因吧,crm今天才完了。主要是接触了几个新技术:
Struts2、poi、ibatis这几个都是以前的项目中用过的。
Jsf、tapestry是这次新接触的,都是界面层的框架,用起来也不难。思路和struts不太一样,传说比较简单方便。不过个人感觉还是struts用着顺手啊,当然springmvc也很顺手,不知道是因为习惯还是什么。jsf和tapestry应用的时候需要知道他们的标签、主
spring里配置使用hibernate的二级缓存几步
antonyup_2006
java spring Hibernate xml cache
.在spring的配置文件中 applicationContent.xml,hibernate部分加入
xml 代码
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hi
JAVA基础面试题
百合不是茶
抽象实现接口 String类 接口继承 抽象类继承实体类 自定义异常
/* * 栈(stack):主要保存基本类型(或者叫内置类型)(char、byte、short、 *int、long、 float、double、boolean)和对象的引用,数据可以共享,速度仅次于 * 寄存器(register),快于堆。堆(heap):用于存储对象。 */ &
让sqlmap文件 "继承" 起来
bijian1013
java ibatis sqlmap
多个项目中使用ibatis , 和数据库表对应的 sqlmap文件(增删改查等基本语句),dao, pojo 都是由工具自动生成的, 现在将这些自动生成的文件放在一个单独的工程中,其它项目工程中通过jar包来引用 ,并通过"继承"为基础的sqlmap文件,dao,pojo 添加新的方法来满足项
精通Oracle10编程SQL(13)开发触发器
bijian1013
oracle 数据库 plsql
/*
*开发触发器
*/
--得到日期是周几
select to_char(sysdate+4,'DY','nls_date_language=AMERICAN') from dual;
select to_char(sysdate,'DY','nls_date_language=AMERICAN') from dual;
--建立BEFORE语句触发器
CREATE O
【EhCache三】EhCache查询
bit1129
ehcache
本文介绍EhCache查询缓存中数据,EhCache提供了类似Hibernate的查询API,可以按照给定的条件进行查询。
要对EhCache进行查询,需要在ehcache.xml中设定要查询的属性
数据准备
@Before
public void setUp() {
//加载EhCache配置文件
Inpu
CXF框架入门实例
白糖_
spring Web 框架 webservice servlet
CXF是apache旗下的开源框架,由Celtix + XFire这两门经典的框架合成,是一套非常流行的web service框架。
它提供了JAX-WS的全面支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用,同时它能与spring进行完美结合。
在apache cxf官网提供
angular.equals
boyitech
AngularJS AngularJS API AnguarJS 中文API angular.equals
angular.equals
描述:
比较两个值或者两个对象是不是 相等。还支持值的类型,正则表达式和数组的比较。 两个值或对象被认为是 相等的前提条件是以下的情况至少能满足一项:
两个值或者对象能通过=== (恒等) 的比较
两个值或者对象是同样类型,并且他们的属性都能通过angular
java-腾讯暑期实习生-输入一个数组A[1,2,...n],求输入B,使得数组B中的第i个数字B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]
bylijinnan
java
这道题的具体思路请参看 何海涛的微博:http://weibo.com/zhedahht
import java.math.BigInteger;
import java.util.Arrays;
public class CreateBFromATencent {
/**
* 题目:输入一个数组A[1,2,...n],求输入B,使得数组B中的第i个数字B[i]=A
FastDFS 的安装和配置 修订版
Chen.H
linux fastDFS 分布式文件系统
FastDFS Home:http://code.google.com/p/fastdfs/
1. 安装
http://code.google.com/p/fastdfs/wiki/Setup http://hi.baidu.com/leolance/blog/item/3c273327978ae55f93580703.html
安装libevent (对libevent的版本要求为1.4.
[强人工智能]拓扑扫描与自适应构造器
comsci
人工智能
当我们面对一个有限拓扑网络的时候,在对已知的拓扑结构进行分析之后,发现在连通点之后,还存在若干个子网络,且这些网络的结构是未知的,数据库中并未存在这些网络的拓扑结构数据....这个时候,我们该怎么办呢?
那么,现在我们必须设计新的模块和代码包来处理上面的问题
oracle merge into的用法
daizj
oracle sql merget into
Oracle中merge into的使用
http://blog.csdn.net/yuzhic/article/details/1896878
http://blog.csdn.net/macle2010/article/details/5980965
该命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据. ORACLE 9i 中,使用此命令必须同时指定UPDATE 和INSE
不适合使用Hadoop的场景
datamachine
hadoop
转自:http://dev.yesky.com/296/35381296.shtml。
Hadoop通常被认定是能够帮助你解决所有问题的唯一方案。 当人们提到“大数据”或是“数据分析”等相关问题的时候,会听到脱口而出的回答:Hadoop! 实际上Hadoop被设计和建造出来,是用来解决一系列特定问题的。对某些问题来说,Hadoop至多算是一个不好的选择,对另一些问题来说,选择Ha
YII findAll的用法
dcj3sjt126com
yii
看文档比较糊涂,其实挺简单的:
$predictions=Prediction::model()->findAll("uid=:uid",array(":uid"=>10));
第一个参数是选择条件:”uid=10″。其中:uid是一个占位符,在后面的array(“:uid”=>10)对齐进行了赋值;
更完善的查询需要
vim 常用 NERDTree 快捷键
dcj3sjt126com
vim
下面给大家整理了一些vim NERDTree的常用快捷键了,这里几乎包括了所有的快捷键了,希望文章对各位会带来帮助。
切换工作台和目录
ctrl + w + h 光标 focus 左侧树形目录ctrl + w + l 光标 focus 右侧文件显示窗口ctrl + w + w 光标自动在左右侧窗口切换ctrl + w + r 移动当前窗口的布局位置
o 在已有窗口中打开文件、目录或书签,并跳
Java把目录下的文件打印出来
蕃薯耀
列出目录下的文件 文件夹下面的文件 目录下的文件
Java把目录下的文件打印出来
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
蕃薯耀 2015年7月11日 11:02:
linux远程桌面----VNCServer与rdesktop
hanqunfeng
Desktop
windows远程桌面到linux,需要在linux上安装vncserver,并开启vnc服务,同时需要在windows下使用vnc-viewer访问Linux。vncserver同时支持linux远程桌面到linux。
linux远程桌面到windows,需要在linux上安装rdesktop,同时开启windows的远程桌面访问。
下面分别介绍,以windo
guava中的join和split功能
jackyrong
java
guava库中,包含了很好的join和split的功能,例子如下:
1) 将LIST转换为使用字符串连接的字符串
List<String> names = Lists.newArrayList("John", "Jane", "Adam", "Tom");
Web开发技术十年发展历程
lampcy
android Web 浏览器 html5
回顾web开发技术这十年发展历程:
Ajax
03年的时候我上六年级,那时候网吧刚在小县城的角落萌生。传奇,大话西游第一代网游一时风靡。我抱着试一试的心态给了网吧老板两块钱想申请个号玩玩,然后接下来的一个小时我一直在,注,册,账,号。
彼时网吧用的512k的带宽,注册的时候,填了一堆信息,提交,页面跳转,嘣,”您填写的信息有误,请重填”。然后跳转回注册页面,以此循环。我现在时常想,如果当时a
架构师之mima-----------------mina的非NIO控制IOBuffer(说得比较好)
nannan408
buffer
1.前言。
如题。
2.代码。
IoService
IoService是一个接口,有两种实现:IoAcceptor和IoConnector;其中IoAcceptor是针对Server端的实现,IoConnector是针对Client端的实现;IoService的职责包括:
1、监听器管理
2、IoHandler
3、IoSession
ORA-00054:resource busy and acquire with NOWAIT specified
Everyday都不同
oracle session Lock
[Oracle]
今天对一个数据量很大的表进行操作时,出现如题所示的异常。此时表明数据库的事务处于“忙”的状态,而且被lock了,所以必须先关闭占用的session。
step1,查看被lock的session:
select t2.username, t2.sid, t2.serial#, t2.logon_time
from v$locked_obj
javascript学习笔记
tntxia
JavaScript
javascript里面有6种基本类型的值:number、string、boolean、object、function和undefined。number:就是数字值,包括整数、小数、NaN、正负无穷。string:字符串类型、单双引号引起来的内容。boolean:true、false object:表示所有的javascript对象,不用多说function:我们熟悉的方法,也就是
Java enum的用法详解
xieke90
enum 枚举
Java中枚举实现的分析:
示例:
public static enum SEVERITY{
INFO,WARN,ERROR
}
enum很像特殊的class,实际上enum声明定义的类型就是一个类。 而这些类都是类库中Enum类的子类 (java.l