并发编程的故事
文章平均质量分 86
菜鸡小张.
这个作者很懒,什么都没留下…
展开
-
并发编程的故事——JUC
第一次判断的意思是如果还有其它线程想要进来,那么发现乐观锁(U.compareAndSwapInt(this, SIZECTL, sc, -1)已经被使用了,那么就进入下一次循环,发现sizeCtl是-1也就是有线程正在创建表,那么就yield放弃cpu使用权相当于就进入阻塞,下一次苏醒进入创建的时候发现这个时候table已经不是null了,再次回到循环,然后回到while循环的时候结束。所以e现在指向的是1->null,e.next很自然就是35->1->null,切换到线程2就会死链,为什么会这样?原创 2023-09-04 22:56:51 · 176 阅读 · 0 评论 -
并发编程的故事——共享模式之无锁
其实就是CPU的缓存都是以缓存行进行的存储,cpu1和cpu2读取了内存块1和2进入自己的缓存行,导致的问题就是一方的修改导致对方的缓存失效,那么就要去修改内存再通知其它缓存块。解决办法就是通过Contended注解,把内存块分成两行相当于就是增加padding空块,然后让Cell数据存到内存块的下一行,让cpu读取的时候存入不同的缓存行,那么就不会出现在修改的时候还需要去修改另一个cpu的缓存。第二个判断是casBasy是0的时候,而且cells没有被修改,把casBusy改为1,相当于就是上锁。原创 2023-09-01 04:47:20 · 225 阅读 · 0 评论 -
并发编程的故事——共享模型之内存
关键就是if(INSTANCE==null)是一个在monitor之外的代码,那么产生的问题就是在执行INSTANCE=new Singleton()的时候,他并不是一个原子操作,包括了invokespecial执行构造方法指令和putstatic给引用赋值(找到对象的堆内存地址)t线程如果频繁读取一个静态变量,那么JIT编译器会把它存入到线程的缓存,那么就算主线程修改了主存中的静态变量也没有任何作用,因为t线程读取的是缓存里面的。单例模式为了防止多次加锁,可以先判空之后,再加锁,再判空。原创 2023-09-01 03:57:02 · 218 阅读 · 0 评论 -
并发编程的故事——并发之共享模型
接着就是把对应锁记录的锁信息与obj进行交换,比如说把01改成了00告诉obj这是一个轻量级锁,而且告诉了obj锁记录的地址,相当于就是给obj贴上是谁的锁的标签。其实就是竞争轻量级锁的时候,没有地方给竞争的线程放着,那么这个时候就需要把轻量级锁转换成重量级锁monitor,其实就是把obj的markword指向monitor。下面的代码出现的问题就是线程1判断成功之后切换,刚好释放了锁,然后就是线程2获取锁进行判断,再次切换线程1获取锁处理put,切换线程2也可以获取锁处理put。原创 2023-09-01 03:12:49 · 335 阅读 · 1 评论 -
并发编程的故事——Java线程
其实就是一个锁的支持类,它的park方法可以模拟sleep把线程进行阻塞,但是需要标记是false的时候。而且这里需要给主线程睡眠一会,不然t1线程还没睡眠,主线程就已经调用打断,那么这个时候的打断是打断t1,并且加上打断标记,但是打断睡眠并不会有打断标记。先分配栈给线程,线程调用main方法,在栈分配一个栈帧给main方法,栈帧保存锁记录、局部变量表、操作数栈、返回地址(返回到原来的栈帧方法的下一条指令)每次开启一个线程都会产生一个线程的栈给线程使用,实际上就是一开始分配的虚拟机栈。原创 2023-09-01 01:38:47 · 188 阅读 · 0 评论 -
并发编程的故事——进程和线程
进程:资源分配的最小单位,是线程的容器。运行的程序,负责管理IO和内存,以及指令的执行线程:其实就是指令流,进程的子集,进程可以分多个线程运行区别:1、进程是最小资源分配,线程是最小调度(指的是cpu切换指令流执行的调度)2、线程是进程的子集3、同样的计算机里面进程通讯是IPC方式,不同计算机就要通过协议比如HTTP4、线程切换的成本更低,比如CPU需要并发执行进程或者是线程,线程比较轻量,切换消耗的CPU时间也更小。原创 2023-08-31 05:36:02 · 42 阅读 · 0 评论