![](https://img-blog.csdnimg.cn/20190927151117521.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
java多线程
java多线程
.net core game
致力于.net core全栈游戏服务器开发
展开
-
【非常非常非常重要的结论!!!!】以CompletableFuture为例子(深刻理解父任务等待子任务,但是父任务占满线程池导致子任务无法程序最终程序卡死的问题) 2.CPU缓存
思考:用arthas的jvm命令查看下,其实并不是死锁,只是父任务把线程池占用满了,子任务无法执行了,但是父任务又等待子任务,程序卡死那了。xdb中,任何之中又提交其它的任务,同时出现get等待,则是游可能出现卡死的问题。2)任务套任务(全回调的方式),但是不出现父任务等待子任务时,是不会卡死那的。思考:可以看出来,只要不出现“父任务等待子任务完成“,则不会有任何问题。如果是: 一个事务中,又call其它,这属于同步执行,是不会有任何问题。1)父任务等待子任务时,出现程序卡死的问题。原创 2024-03-24 10:21:41 · 342 阅读 · 0 评论 -
guava的回调方案
【代码】guava的回调方案。原创 2024-03-06 10:37:11 · 126 阅读 · 0 评论 -
玩家切换场景时的一个小实验
【代码】玩家切换场景时的一个小实验。原创 2024-03-01 12:54:57 · 154 阅读 · 1 评论 -
[CountDownLatch] 1.实现等待TcpServer启动完毕后再发射事件 2.使用CompletableFuture代替CountDownLatch将阻塞封装到内部
也不能说:直接就启动一个线程,不然没办法发射出“服务器启动”这个事件。有时候,我们希望NettyServer启动时不能说卡主主线程。这时就可以使用此类执行完毕后,通知下主线程。总结:可以看出来,是单独的线程启动,但是可以控制住顺序了。原创 2024-02-22 23:59:23 · 292 阅读 · 0 评论 -
高性能RPC实现基础之CompletableFuture
package org.example.testcf;import java.util.concurrent.*;import java.util.function.Supplier;public class Main { static ExecutorService es = Executors.newSingleThreadExecutor(); public static void main(String[] args) throws InterruptedExcepti.原创 2021-11-04 11:40:30 · 303 阅读 · 0 评论 -
【CompletableFuture完成游戏服务器中各类业务线程间的交互】1.玩家线程和好友线程的交互 2.玩家线程和排行榜线程的交互 3.supplyAsync(带返回值的)和runAsync
2.任务有依赖关系,并且等待所有任务执行完毕。1.IO线程执行阻塞任务,之后回到逻辑线程。原创 2024-01-19 15:14:46 · 550 阅读 · 0 评论 -
【多生产者多消费者实现】1.Runnable用于实现线程任务 2.BlockingQueue用于线程数据交换
1)产品package juc.blockingqueue;public class Product { public Product() { } @Override public String toString() { return "Product$" + this.hashCode(); }}2)生产者package juc.blockingqueue;import java.util.concurrent.Blo原创 2020-06-29 14:30:20 · 877 阅读 · 1 评论 -
【BlockingQueue】1.drainTo实现将当前阻塞队列中的信息全部转移到List中 2.poll实现队列中没有值也不阻塞
package org.example.testDrainTo;import java.util.ArrayList;import java.util.List;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;public class Main { public static void main(String[] args) { Bloc.原创 2022-03-02 19:33:17 · 3443 阅读 · 0 评论 -
[原子类AtomicInteger] 1.getAndAdd(x)实现添加任意值 getAndIncrement()实现i++ 2.compareAndSet实现比较操作
package org.example.testatomic;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;public class Main { public static void main(String[] args) throws InterruptedException { AtomicInteger atomicNum = new At.原创 2021-12-14 16:06:06 · 759 阅读 · 0 评论 -
【DCL要加volatile的真正原因】
最起码要有这2步,实际在jvm层面要做更多的事情,也就是说:会有"不完全对象"(构造函数未执行)的问题。同时防止cpu乱序执行指令。new一个对象的时候,其实在jvm层面,是要做很多事情的,根本不是一步完成的。原创 2022-09-17 12:37:06 · 179 阅读 · 0 评论 -
【 LockSupport的park和unpark】案例之通过数字交替打印
unpark可以先执行,这样子等下次park时,并不会导致线程阻塞。unpark相当于一个海克斯护盾一样。这是和wait和notify不同的地方。原创 2022-08-24 16:34:13 · 183 阅读 · 0 评论 -
[executorService.invokeAll+Callable实现批量等待任务并发执行】 1.多线程导表案例 2.使用for循环+Future的isDone()实现等待源码分析
|-- src | |-- main | | |-- java | | ...原创 2021-09-21 17:42:25 · 580 阅读 · 0 评论 -
【Java多线程涉及的知识】1.缓存引起可见性问题2.synchronized+volatile3.AQS 4.并发包 5.chm 6.BlockingQueue 7.线程池 8.线程封闭9.cas
1)硬件、内存、硬盘IO四度不匹配: 引起可见性、原子性、有序性问题2)synchronized、volatile3)AQS:ReentrantLock+Condition4)JUC:CountDownLatch:计数器、Semaphore: 限流、CyclicBarrier:栅栏5)并发集合:ConcurrentHashMap6)阻塞队列7)线程池8)ThreadLocal: 线程封闭...原创 2020-09-23 14:50:06 · 139 阅读 · 0 评论 -
【异步IO】 1.AtomicReference持有对象 2.解决跨线程对象传递问题 3.使用FunctionInterface实现匿名函数 4.体会IO线程和逻辑线程的通信
AtomicReference<Integer> num = new AtomicReference<>(); num.set(11); Integer integer = num.get(); System.out.println(integer);这样子在异步操作中跨线程操作同一个对象,就可以用这个,避免final之类的提示错误。......原创 2022-04-05 02:14:44 · 1801 阅读 · 0 评论 -
【切场景时的线程安全问题】理论基础:多线程访问,但是同一时刻只有一个线程能访问到,那就是线程安全的
SceneManager.javaMap allRolesMap = new ConcurrentHashMap();Scene.java Map humanObjects = new ConcurrentHashMap();在每次玩家切换地图时,都会从全局的SceneManager中拷贝SceneRole到Scene中,之后的修改,也都是发的消息包装为Task到这个场景线程中,从而进行修改这个SceneRole上的普通的Se.........原创 2022-06-07 11:24:23 · 237 阅读 · 0 评论 -
【Vector线程安全问题】1.多个线程都取最后一个元素索引 2.一起删除最后一个元素: 警惕2个原子操作合并一起整体不是原子导致的线程安全问题
1)使用线程安全的Vector进行操作,多线程并发的情况下,一定是线程安全的吗?答案:不是原因:虽然Vector的大部分方法都加上了synchronized同步块,但是比如如下需求:void deleteLastEle(){ int lastIndex = vec.size() - 1; // 1 vec.remove(lastIndex); // 2...原创 2020-03-15 21:04:12 · 269 阅读 · 0 评论 -
【线程间通讯的2种方式】1.wait+notify 2.BlockingQueue
1.wait在一个线程wait后等待obj.wait()另外一个线程完成计算,然后obj.notify这时,另外一个线程就苏醒,拿到结果接着执行2.BlockingQueueblockQueue.take() 这样子就等待在这里另外一个线程通过offer或者add往里面添加数据,添加完毕后,另外一个线程take到数据就苏醒过来,拿到另外一个线程的执行结果。...原创 2021-06-25 12:46:01 · 89 阅读 · 0 评论 -
ThreadLocal在mysql数据库中的应用场景
由于一个业务操作,比如:借阅图书,那么必然多个mysql数据库操作组成,为了保证事务,必须保证对这个业务的操作是同一个链接,由于这个客户端的这次请求,必然对应一个线程,那么这几个数据库处理那么就可以用ThreadLocal取数据库连接,这样子就可以保证是同一个链接,为回滚也做了准备。更广维度的,还可以扩展到一次Http请求中,可以在本次请求的2个回调函数比如:recvHttpRequest endHttpRequest这样子来用ThreadLocal管理本次的连接。...原创 2021-08-01 20:42:18 · 221 阅读 · 0 评论 -
【happen before】
jvm在设计的时候,将提前可知的先后逻辑关系的程序,内置jvm中。jvm内置的,保证先后逻辑关系的保障。原创 2022-11-21 15:57:22 · 53 阅读 · 0 评论 -
【java异步核心原理】1.动手实现Netty ChannelFuture机制 2.ExecutorService实现多线程业务计算并把结果包装为Task提交到另外一个单线程池执行从而拿到结果
Callback.javapackage async;@FunctionalInterfacepublic interface Callback<T> { void call(T t);}ChannelFuture.javapackage async;public interface ChannelFuture<IN, OUT> { void addListener(int hashId, Task<IN, OUT> task原创 2021-07-20 01:08:23 · 278 阅读 · 0 评论 -
[多线程之间通过队列倒数据]1.以转账和1读1写依然不安全为例子 2.想清楚数据是哪个线程维护的并始终让这个线程负责数据的修改(核心)
Constant.javapackage org.example.account.constant;public class Constant { /** * 有多少个账户 */ public static int ACCOUNT_NUM = 100; /** * 每个人初始化的金币 */ public static int MONEY = 100; /** * 发起转账数量 */ pu原创 2021-12-26 12:28:10 · 250 阅读 · 0 评论 -
张振华《如何理解应用Java多线程与并发编程》知乎Live学习总结
1)线程与进程线程: cpu执行的最小单元。进程:计算机资源分配的最小单元。2)并发与并行并发:是逻辑概念,是一个线程同时快速的切换干多个事情,我们感觉是在同时,其实只是快速的切换。并行:是物理上的同时发生,真的多个cpu同时执行。3)创建线程,常见的有3种:继承Thread实现Runnable接口实现Callable接口(待返回值)。4)sleep和wait对比sleep:释放cpu执行权限 ,但是不释放锁,别人进不来。wait:释放权限+释放锁。 指的一定原创 2021-10-08 17:04:48 · 137 阅读 · 0 评论 -
【volatile使用实战】
第1版:Map<Integer,ConfLevel> map = xxx;void init(){}这样子的话,等于热更会在另外一个线程执行,会有多线程访问的问题。一个业务线程在遍历,另一个热更线程在修改。第2版:Map<Integer,ConfLevel> map;void init(){ Map<Integer,ConfLevel> temp = xxx; // 配置初始化用临时变量保存 map = local原创 2022-04-07 11:29:42 · 279 阅读 · 0 评论 -
【管程模型-并发编程的万能钥匙 】1.管程指的是管理共享变量以及对共享变量的操作过程,让他们支持并发 2.并发2大核心问题:互斥:同一时刻只有一个能访问到临界资源 同步:2个线程间的通信与协作
参考:3.8、管程:并发编程的万能钥匙 - 知乎 (zhihu.com)原创 2022-11-20 15:33:22 · 155 阅读 · 0 评论 -
【jmm】1.解决平台一致性的问题 2.又引起可见性的问题 3.volatile
出现原因:因为不同平台,硬件层面,对内存可见性有可能不一致,因此jmm的出现就是在不同平台抽象出一致的行为。允许直接操作共享内存,因此无可见性的问题,但是:有可能一个线程修改完后,并不会立即修改写回主内存。缺点:只允许操作本地方法栈,不允许直接操作共享内存。原创 2022-11-22 22:37:53 · 61 阅读 · 0 评论 -
【等待唤醒机制】1.以包子铺生产包子,吃货吃包子为例子 2.synchronized+wait+notify
1)线程的6种状态 NEW(新建状态): 至今尚未启动的线程处于这种状态. RUNNABLE(运行状态): 正在java虚拟机中执行的线程处于这种状态. BLOCKED(阻塞状态): 受阻塞并等待某个监视器锁的线程处于这种状态. 等待CPU资源,有则可能执行; start后开始争夺CPU的执行资源,没有抢到就进入到阻塞状态; 获取到锁对象,就进入到运行状态; WAIT...原创 2020-02-20 17:01:29 · 435 阅读 · 0 评论 -
【屏障的2种实现】1.lock 与 fcene(mfcene、lfcene、sfcene) 2.volatile和synchronized其实都是屏障的实现,会保证从主内存读从而保证可见性
mfcene:类似于在硬件层面搞了一个队列,这样子cpu之间本身就竞争,效率相对更低。lock:是一个cpu在写的时候,另外一个cpu要阻塞着。原创 2022-11-21 15:54:13 · 67 阅读 · 0 评论 -
【synchronized是可以保证变量的可见性的】
3.其实,synchronized在修改了本地内存的变量后,解锁前会把本地内存修改的内容刷新到主内存中,确保了共享变量的值是最新的,也就保证了可见性。1.我们都知道,jmm的存在导致java的线程其实读取的都是本地的副本(为何出现jmm,其实是为了实现平台一致性),因此会出现可见性问题。2.猜想:那么加了synchronized后,如果还不能保证可见性,那就没有办法保证可见性了呀!select:其实也是上锁,因此必定能读到最新的数据。get: 修改时加锁,这样子也保证能取到最新的数据。原创 2022-11-24 13:23:56 · 714 阅读 · 0 评论 -
[synchronized] 实现多线程下共同变量访问时的并发安全(最基础版本)
1)不安全的代码package com.atguigu.test;public class Test { public static int count = 0; public static void add() { count++; } public static void sub() { count--; }...原创 2020-02-17 15:14:39 · 163 阅读 · 0 评论 -
【线程间通讯之wait和notify】 1.notify后wait的线程无法立刻唤醒 2.要等到notify的线程退出synchronized后才能去真正抢锁 3.N个线程交替打印数字(理解内部类)
Data.javapackage org.example.testwaitnotify;public class Data { private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; }}ThreadA.javapackage org.exa原创 2021-10-08 21:07:12 · 723 阅读 · 0 评论 -
1.synchronized(锁升级) 2.ReentrantLock(先cas、再加入同步队列、在park进行系统调用被阻塞)
1)synchronized是有锁升级的过程。2)ReentrantLock是先尝试CAS自旋,然后才会被加入同步队列。 最后调用park,进行系统调用,被阻塞。原创 2022-11-20 15:25:14 · 563 阅读 · 0 评论 -
【ConcurrentSkipListMap】
key是有序的,因此可以看做是并发的TreeMap。插入和删除有可能会引起节点Level的变更。从最上面开始查找,最后层层往下查。原创 2023-08-13 23:29:06 · 93 阅读 · 0 评论 -
ReentrantLock中的Condition的用法
在rpc中,我们也可以用这个await来搞。当然了还有CountDownLatch或者CompletableFuture也有提供超时的方法。其实Condition或者说wait和notify/notifyAll,我们是在阻塞队列中经常使用。生产者消费者模式嘛,一个线程生成数据,有了数据后,通知其它线程取。也就是await方法,是位于lock之间。原创 2023-08-05 20:49:35 · 251 阅读 · 0 评论 -
ConcurrentLinkedQueue代替LinkedBlockingQueue当做任务队列
2.LinkedBlockingQueue原理是:这种阻塞队列底层是用LockSupport实现,并且依赖锁的阻塞与唤醒。另一种就是:cas+volatile,毕竟cas是用于赋值用的,跟可见性没什么关系。3.CAS+volatile:保证线程安全。其实还是:悲观和乐观的2种实现方式。1.并发容器、基于链表、单线链表。一种就是:锁+唤醒机制。原创 2023-08-05 15:17:42 · 48 阅读 · 0 评论 -
【ReentrantLock源码分析】1.xdb中的使用 2.获取和阻塞(阻塞前的一些死心不改)的源码
1.xdb中的使用例子在xdb中,我们大概执行业务时的流程简化如下:思考:为啥我们用ReentrankLock而不是synchronized呢?因为:我们需要提供可重入的特性,而且释放是要控制在:事务完成后(不管是回滚了还是提交成功了)才释放锁,因此要使用这种显示锁。2.源码分析step1实现如下:可以看出来,默认情况下,是非公平锁,想想目前我还没有遇到要用公平锁的情况。step2接下来是上锁:进入到acquire里面:这里走非公平下的获取:再次进入:既然没有原创 2022-12-03 11:54:00 · 170 阅读 · 0 评论 -
【CopyOnWriteArrayList】
可以看出来,get方法是不加锁的,这样子再高并发下,读多写少时,可以减少很多的锁竞争。原创 2022-11-10 16:53:26 · 71 阅读 · 0 评论 -
ConcurrentHashMap解决Map边遍历边修改的并发操作异常
比如:mmo游戏中,在Tick中,在tickTask对应的线程中进行tickSceneService中的每一个Scene。遍历它的线程和修改的线程不是同一个线程,那么就可能会出现并发安全的问题,修改的话:必须保证,始终是一个线程。在SceneService对应的MapThread中去修改。此时修改为:ConcurrentHashMap即可!那依然会出现:并发修改的错误。...原创 2022-08-12 17:40:44 · 1822 阅读 · 0 评论 -
【ConcurrentHashSet】并发安全的Set(guava中还是有不少有价值的库的)
Set<Object> set = Sets.newConcurrentHashSet(); for (int i = 0; i < 100; i++) { new Thread(() -> { int n = ThreadLocalRandom.current().nextInt(100); if (n > 50) { set.a..原创 2022-03-18 18:29:44 · 688 阅读 · 0 评论 -
[ConcurrentSkipListSet] 1.并发安全的Set 2. 只不过内部有排序 3.可以用Guava的ConcurrentHashSet代替
package org.example.testConcurrentSkipListSet;import java.util.Iterator;import java.util.Set;import java.util.concurrent.ConcurrentSkipListSet;public class Main { // private static Set<String> set = new TreeSet<>(); private st.原创 2022-02-16 10:20:26 · 322 阅读 · 0 评论 -
[LoadingCache] 1.相当于带LRU的ConcurrentHashMap
package org.example.testCache;import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import lombok.AllArgsConstructor;import lombok.Getter;import lombok.Setter;import lombok.ToString;import java.util.concurrent.TimeUnit;.原创 2022-01-25 11:08:51 · 349 阅读 · 0 评论