JUC笔记(二):悲观锁
JUC笔记(二):悲观锁共享变量带来的问题举一个简单的例子:
线程一和线程二都需要去改变一个静态变量i = 0
线程一将 i++
线程二将 i--
由于i++和i--都并非原子操作,在编译成字节码以后会拆分成多个人字节码指令:
i++
1234getstatic i //获取静态变量iiconst_1 //准备常量1iadd //自增putstatic i //修改以后存入静态变量i
i--
1234getstatic i //获取静态变量iiconst_1 //准备常量1isub //自减putstatic i //修改以后存入静态变量i
由于线程一和线程二并发执行,CPU会切换不同的线程,这导致了,CPU运行时的真实情况并不一定是先执行完线程一的i++的所有指令再执行线程二的i–,而是可能会出现很多种情况,如下。最终 i 的结果为 -1,与预期的不同,出现了并发问题
相关概念临界区:一段代码块内如果存在对共享资源的多线程读写操作,称这块代码块为临界区。
竞态条件:多个线程在临界 ...
JUC笔记(一):线程基础
JUC笔记(一):线程基础创建线程方法一:直接使用Thread
1234567Thead t = new Tread() { @Override public void run() { //执行的任务 }};t.start();
方法二:使用runnable
12345678910111213Runnable runnable = new Runnable() { public void run() { //要执行的任务 }};// Thread t = new Thread(runnable, "线程名称");Thread t = new Thread(runnable);//启动线程t.start();//简化new Thread(() -> { //要执行的任务}).start();
简单的源码解析
1234567891011121314151617181920public Thread( ...