JUC(二)
1、CAS1.1、概述
结合JMM线程的工作内存,主内存,副本之类的知识点。CAS主要对副本写回主内存进行了限定要求。主存有一个变量为num,其值为5,称之为A,A指代主存num的值Thread1从主内存拷贝副本到自己的工作内存,此时的副本称之为B,B指代副本num = 5Thread1将num修改为2019,此时称之为C,C指代副本num = 2019Thread1将修改过的num写回主内存时,做如下事情:将B与A进行比较,如果相等,说明在我Thread1一顿猛操作的期间,没有第二个线程动过num,所以我Thread1可以大胆的将新num,也就是C,写回内存;
如果不相等,说明在我Thread1操作期间,有人先我一步动过了num,把它给改变了,那我之前的一顿操作都是在旧数据的基础上干的,其实就是白干了,所以无法写回内存。
public static void demo1() { // 主内存的值 AtomicInteger atomicInteger = new AtomicInteger(5); // 修改成功返回true atomicInteg ...
JUC(一)
J(java)U(util)C(concurrent)其实就是指上图的三个包。
1、Volatitlejvm提供的轻量级同步机制,它有三个特征
保证可见性
禁止指令重排
不保证原子性
JMM(Java Memory Model)java内存模型,一个非实际存在的抽象概念,是一个组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。
JMM关于同步的规定
加锁前,线程从主存中读取最新的值到工作内存
解锁前,线程将自己的工作内存中的共享变量值写入主存内
加锁解锁,是对同一把锁
JVM运行程序的实体是线程,每个线程进行创建是,JVM都会为其创建该线程独有的工作内存(栈空间)。当线程操作内存中的变量时,需要先将其拷贝到自己的空间,整一个副本,然后在自己的工作内存中对其操作,之后,将副本写回主内存
从上述的描述,可以看到:在多线程并发的情况下,由于存在副本和副本写回这样的步骤,势必会出现类似脏读、幻读、不可重复读的问题。
比如:线程1、线程2将数据进行拷贝到自己的工作内存后,线程1进行数据修改并写回主内存,但是线程2还是使用原 ...
算法-不重复最长字符串
输出 给定字符串中 不重复的最长字串的 字符个数public static int lengthOfLongestSubstring(String str){ if (str == null || "".equals(str)){ return 0; } char[] chars = str.toCharArray(); return 0; } public int lengthOfLongestSubstring_(String s) { if(s == null || s.equals("")){ return 0; } char[] arr = s.toCharArray(); int left = 0; int right = 0; int max = 0; bo ...
JAVA基础回顾
1. 8种基本数据类型
2. 面向对象的三大特性
封装
继承
多态
3. ==、hashCode()、 equals()
==
本质:是一个比较运算符
作用:比较俩个对象地址是否相等,基本数据类型比较的是值,引用数据类型比较的是内存地址
hashCode()
本质:返回一个int整数值(哈希码/散列码)
作用:确定该对象在哈希表中的索引位置,也就是说hashCode()在散列表(Java集合中本质是散列表的类,如HashMap,Hashtable,HashSet。)中才有用,在其它情况下没用(例如,创建类的单个对象,或者创建类的对象数组等等)。
hashcode()定义在JDK的Object.java中,所以Java中的任何类都包含有该方法
使用:比较俩个引用类型对象是否相等时,需要重写该方法
equals()
作用:判断俩个引用类型对象的地址是否相等
使用:
1). 类没有重写equals()方法。调用equals()比较该类的俩个对象时,等价与'==',比较的是俩个对象的地址值。
2). 类重写equals()方法。比较的是俩个对象 ...
线程和进程的区别-通俗版
进程是资源分配的最小单位,线程是CPU调度的最小单位
做个简单的比喻进行来理解:
进程=火车,线程=车厢,线程在进程下行进(单纯的车厢无法运行)
一个进程可以包含多个线程(一辆火车可以有多个车厢)
不同进程间数据很难共享(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)
同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)
进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)
进程间不会相互影响,一个线程挂掉将导致整个进程挂掉(一列火车不会影响到另外一列火车,但是如果一列火车上中间的一节车厢着火了,将影响到所有车厢)
进程可以拓展到多机,进程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上)
进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。(比如火车上的洗手间)-”互斥锁”
进程使用的内存地址可以限定使用量(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量”
线程和进程的区别
1.定义进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
2.关系一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
3.区别进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。 ...