大数据知识点梳理(一 JAVA篇)

大数据知识点梳理(一)

本文参考资料链接每个阶段一一列举,仅供学习使用

JAVA基础简述以及常见面试题

一.数据类型转换

java数据类型转换详述
Java中,经常可以遇到类型转换的场景,从变量的定义到复制、数值变量的计算到方法的参数传递、基类与派生类间的造型等,随处可见类型转换的身影。Java中的类型转换在Java编码中具有重要的作用。

1.基本数据类型的类型转换
– a. 基本数据类型中类型的自动提升
数值类型在内存中直接存储其本身的值,对于不同的数值类型,内存中会分配相应的大小去存储。如:byte类型的变量占用8位,int类型变量占用32位等。相应的,不同的数值类型会有与其存储空间相匹配的取值范围。具体如下所示:在这里插入图片描述
图中依次表示了各数值类型的字节数和相应的取值范围。在Java中,整数类型(byte/short/int/long)中,对于未声明数据类型的整形,其默认类型为int型。在浮点类型(float/double)中,对于未声明数据类型的浮点型,默认为double型。

-- b. 隐式类型转换
上面的例子中既有隐式类型转换, 也有强制类型转换, 那么什么是隐式类型转换呢?

隐式转换也叫作自动类型转换, 由系统自动完成.
从存储范围小的类型到存储范围大的类型.
byte ->short(char)->int->long->float->double

--c. 显示类型转换
显示类型转换也叫作强制类型转换, 是从存储范围大的类型到存储范围小的类型.

当我们需要将数值范围较大的数值类型赋给数值范围较小的数值类型变量时,由于此时可能会丢失精度(1讲到的从int到k型的隐式转换除外),因此,需要人为进行转换。我们称之为强制类型转换。
double→float→long→int→short(char)→byte
在这里插入图片描述
–d. 进行数学运算时的数据类型自动提升与可能需要的强制类型转换
当进行数学运算时,数据类型会自动发生提升到运算符左右之较大者,以此类推。当将最后的运算结果赋值给指定的数值类型时,可能需要进行强制类型转换。例如:
在这里插入图片描述

二.运算符

运算符详解
&(位与)
&按位与的运算规则是将两边的数转换为二进制位,然后运算最终值,运算规则即(两个为真才为真)
&&(逻辑与)
&&逻辑与也称为短路逻辑与,先运算&&左边的表达式,一旦为假,后续不管多少表达式,均不再计算,一个为真,再计算右边的表达式,两个为真才为真。
|(位或)
|按位或和&按位与计算方式都是转换二进制再计算,不同的是运算规则(一个为真即为真)
||(逻辑或)
逻辑或||的运算规则是一个为真即为真,后续不再计算,一个为假再计算右边的表达式。
<<(左移运算符)
左移运算符<<使指定值的所有位都左移规定的次数。
右移运算符(>>)
凡位运算符都是把值先转换成二进制再进行后续的处理,5的二进制位是0000 0101,右移两位就是把101左移后为0000 0001,
正数左边缺少的位数补0,负数左边缺少的位数补1,等于除于2的n次方,结果为1
~(取反运算符)
取反就是1为0,0为1,5的二进制位是0000 0101,取反后为1111 1010,值为-6
^(异或运算符)
异或运算符顾名思义,异就是不同,其运算规则为10 = 1 , 1^1 = 0 , 0^1 = 1 , 0^0 = 0
5的二进制位是0000 0101 , 9的二进制位是0000 1001,也就是0101 ^ 1001,结果为1100 , 00001100的十进制位是12
无符号右移运算符(>>>)
无符号右移运算符和右移运算符的主要区别在于负数的计算,因为无符号右移是高位补0,移多少位补多少个0

三.流程控制

java流程控制详解
条件语句
1.if条件语句
  使用if条件语句,可选择是否要执行紧跟在条件之后的那个语句。关键字if之后是作为条件的“布尔表达式”,如果该表达式返回true,则执行其后的语句;若为false,则不执行if后的语句。可分为简单的if条件语句、if···else语句和if···else if多分支语句。

int a = 100;
if(a == 100) {
System.out.println(a);
}

2.if···else语句
if···else语句是条件语句中最常用的一种形式,它会针对某种条件有选择的作出处理。通常表现为“如果满足某种条件,就进行某种处理,否则就进行另一种处理”。
  if后的()内的表达式必须是boolean型的。如果为true,则执行if后的复合语句;如果为false,则执行else后的复合语句。

public class Getifelse {

public static void main(String[] args) {
    int math = 80;        // 声明,数学成绩为80(及格)
    int english = 50;    // 声明,英语成绩为50(不及格)

    if(math >= 60) {    // if判断语句判断math是否大于等于60
        System.out.println("math has passed");
    } else {            // if条件不成立
        System.out.println("math has not passed");
    }

    if(english >= 60) {    // if判断语句判断english是否大于等于60
        System.out.println("english has passed");
    } else {            // if条件不成立
        System.out.println("english has not passed");
    }
}

}

3.if···else if多分支语句
if···else if多分支语句用于针对某一事件的多种情况进行处理。通常表现为“如果满足某种条件”,就进行某种处理,否则,如果满足另一种条件,则进行另一种处理。

public class GetTerm {

public static void main(String[] args) {
    int x = 40;

    if(x > 60) {
        System.out.println("x的值大于60");
    } else if (x > 30) {
        System.out.println("x的值大于30但小于60");
    } else if (x > 0) {
        System.out.println("x的值大于0但小于30");
    } else {
        System.out.println("x的值小于等于0");
    }
}

}

4.switch多分支语句
  switch语句是一种比较简单明了的多选一的选择,在Java语言中,可以用switch语句将动作组织起来进行多选一。语法格式如下:

switch(表达式)
{
case 常量值1:
语句块1
[break;]

case 常量值n:
语句块2
[break;]
default:
语句块 n+1;
[break;]
}

循环语句
1.while循环语句
  while循环语句的循环方式为利用一个条件来控制是否要继续反复执行这个语句。

假设现在有1~10十个数字,我们要将它们相加求和,在学习while之前可能会直接用+运算符从1加到10,也就是1+2+3+4+5+6+7+8+9+10,但如果现在需要从1加到1万呢?10万?所以,我们要引入while循环来进行循环相加,如下:

public class GetSum {

public static void main(String[] args) {
    int x = 1;            // 定义初值
    int sum = 0;        // 定义求和变量,用于存储相加后的结果

    while(x <= 10) {
        sum += x;        // 循环相加,也即    sum = sum + x;
        x++;
    }
    System.out.println(sum);
}

}

2.do···while循环语句
  do···while循环语句与while循环语句的区别是,while循环语句先判断条件是否成立再执行循环体,而do···while循环语句则先执行一次循环后,再判断条件是否成立。也即do···while至少执行一次。语法格式如下:

do
{
执行语句
} while (条件表达式);

3.for循环语句
  for循环语句是Java程序设计中最有用的循环语句之一。一个for循环可以用来重复执行某条语句,知道某个条件得到满足。语法格式如下:

for(表达式1; 表达式2; 表达式3)
{
语句序列
}

跳转语句
1.break语句
  break语句刚刚在switch中已经见过了,是用来中止case的。实际上break语句在for、while、do···while循环语句中,用于强行退出当前循环,为什么说是当前循环呢,因为break只能跳出离它最近的那个循环的循环体,假设有两个循环嵌套使用,break用在内层循环下,则break只能跳出内层循环,如下:

for(int i=0; i<n; i++) { // 外层循环
for(int j=0; j<n ;j++) { // 内层循环
break;
}
}

2.continue语句
  continue语句只能用于for、while、do···while循环语句中,用于让程序直接跳过其后面的语句,进行下一次循环。
  例:输出10以内的所有奇数

public class ContinueDemo {

public static void main(String[] args) {
    int i = 0;

    while(i < 10) {
        i++;

        if(i%2 == 0) {    // 能被2整除,是偶数
            continue;    // 跳过当前循环
        }

        System.out.print(i + " ");
    }
}

}

3.return语句
return语句可以从一个方法返回,并把控制权交给调用它的语句。

public void getName() {
return name;
}

四.函数

JAVA函数(方法)
函数是定义在类中的一段独立的代码块,用来实现某个功能。Java中,函数又被称为方法。
函数的主要作用是为了提高代码的复用性。
函数都是在栈内存中运行;运行的函数处在栈顶。
函数格式:修饰符 返回值类型 函数名 ( [ 参数类型1 参数名1,参数类型2 参数名2… ] ){

               //   [    ]    里面表示可选项,即参数不是必须的

               执行语句...

               return  返回值;    //返回值的类型必须与返回值类型一致

                }

函数的重载:
函数的重载是指,在同一个类中,可以定义多个函数名相同、参数列表不同的函数。
参数名相同,参数个数不同,参数列表不同均属于函数重载的情况。注意,函数的重载和返回值类型无关。
调用时通过函数名和参数列表来确定一个函数。

函数的递归:
函数的递归是指在一个函数的内部调用自身的过程。
递归必须要有结束条件,不然就是陷入无限递归的状态,永远无法结束函数的调用。

五.数组,数组的遍历,排序,二维数组

数组 | 数组遍历 | 排序 | 多维(二维)数组
数组
数组是什么?
数组是指一组数据的集合,数组中的每个数据被称作元素。数组里面可以存放任意类型的数据,但是一个数组中的数据类型必须相同。
为什么要使用到数组?
根据前面的学习,如果我们想保存50个类似的数据,需要声明50个对应的变量。这样会显得很麻烦,于是我们使用数组,只需要声明一个数组,就可以存储这些变量了。

数组的常见操作

数组遍历
依次访问数组中的每个元素,这种操作称为数组的遍历,通常使用for循环来进行遍历数组

public class Example01{
public static void main (String [] args){
int [] arr={1,2,3,4,5};
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
//因为i是在变化的 所以arr[i]代表的是数组中的每一元素
}
}
}

数组最值
通过案例来看一下

public class Example01{
public class static void main (String [] args){
int [] arr={1,3,7,5};//定义数组
int max=getMax(arr);//将获取最大值的方法获取到的最大值赋给max
System.out.println(max);//输出最大值
}
static int getMax(int [] arr){
int max=arr[0];//定义变量用来记住最大值,先假设最大值是arr[0]
//for循环遍历数组
for(int x=1;x<arr.length;x++){
if(arr[x]>max){
max=arr[x];
}
}
return max;
}
}

数组排序
比较常用的是冒泡排序。
例如3,9,8,2,5需要进行冒泡排序,过程是这样的:
第一轮:3和9比,3小9大,因此3不动;9和8比,9大8小,因此9和8交换位置;9和2同理,9和5同理,该轮结果:3,8,2,5,9
第二轮对第一轮结果进行排序:原理和第一轮相同,该轮排序结果3,2,5,8,9
第三轮对第二轮结果进行排序:原理同上,该轮排序结果为2,3,5,8,9

冒泡排序的原理是:不断比较数组中相邻两个元素的大小,较小者向上浮,较大者向下沉。
通过代码来看一下刚刚的例子

public class Example02{
public static void main (String [] args){
int [] arr={3,9,8,2,5};
System.out.print(“冒泡排序前:”);
printArray(arr);//打印排序前数组
bubbleSort(arr);//调用冒泡排序方法
System.out.print(“冒泡排序后:”);
printArray(arr);//打印排序后数组
}
//定义打印数组方法(即方法printArray)
public static void printArray(int [] arr){
//循环遍历数组
for(int x=0;x<arr.length;x++){
System.out.print(arr[i]+",")
}
System.out.print("\n")
}
//定义数组排序的方法(冒泡排序,即bubbleSort)
public static void bubbleSort(int [] arr){
//定义外层循环 即控制排序的轮数
//元素排序只需要排元素个数-1轮
for(int i=0;i<arr.length-1;i++){
//定义内层循环 即每一轮是如何排序的
//循环一次,排好一个数,那么再次循环的时候就把需要比较的长度-1,也就是-i
for(int j=0;j<arr.length-i-1){
if (arr[j] > arr[j + 1]) { // 比较相邻元素
// 下面的三行代码用于交换两个元素
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.print(“第” + (i + 1) + “轮排序后:”);
printArray(arr); // 每轮比较结束打印数组元素
}
}
}

多维数组(二维及以上)
二维数组的含义是数组里面还有一个数组(即数组中嵌套数组)。二维数组就像是一栋大楼共有多少层,每层几户人家。
二维数组定义的方式有三种:

//这种方法是已经确定大小的
int [] [] arr=new int[3][4];
//对确定第一层大小的
int [] [] arr=new int[3][];
//不确定大小的,静态初始化时
int [] [] arr={{1,2},{3,4,5,6},{7,8,9}}

六.java面向对象,继承封装多态总结

添加链接描述

	面向对象(Object Oriented)是软件开发方法,一种编程范式。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。
	面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。

继承

继承的概念
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

继承的特性
子类拥有父类非 private 的属性、方法。
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

继承关键字
继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

封装

在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

封装的优点

  1. 良好的封装能够减少耦合。
  2. 类内部的结构可以自由修改。
  3. 可以对成员变量进行更精确的控制。
  4. 隐藏信息,实现细节。

多态

多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:
在这里插入图片描述
多态性是对象多种表现形式的体现。
现实中,比如我们按下 F1 键这个动作:
如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
如果当前在 Word 下弹出的就是 Word 帮助;
在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。

多态的优点

  1. 消除类型之间的耦合关系
  2. 可替换性
  3. 可扩充性
  4. 接口性
  5. 灵活性
  6. 简化性

多态存在的三个必要条件
继承
重写
父类引用指向子类对象

七.抽象类,接口,内部类总结

详述

1.抽象方法、抽象类

抽象方法:
由abstract修饰
只有方法的定义,没有方法的具体实现(连{}都没有)
  由abstract修饰的方法为抽象方法,抽象方法只有方法的定义,没有方法体实现,用一个分号结尾。即:方法五要素中,抽象方法缺少了一个要素(方法体),也可以将抽象方法理解为不完整的方法。

抽象类:
由abstract修饰
包含抽象方法的类必须是抽象类,不包含抽象方法的类也可以声明抽象类(意义不大)
抽象类不能被实例化
抽象类是需要被继承的
子类需要重写抽象类的所有抽象方法—常用
子类也可以声明为抽象类—不常用
抽象类的意义:
封装子类所共有的属性和行为—代码复用
为所有子类提供一种统一的类型—向上造型
可以包含抽象方法,为所有子类提供了统一的入口,子类的实现不同,但入口是一致的
  由abstract修饰的类为抽象类,抽象类是不能实例化对象的,而一个类不能实例化是没有意义的,所以需要定义类来继承抽象类,它的子类必须重写所有的抽象方法,除非该类也声明为抽象类。
  抽象类不可以被实例化

继承抽象类
  一个类继承抽象类后,必须实现其抽象方法,不同的子类可以有不同的实现。

抽象类的意义
为其子类提供一个公共的类型(父类引用指向子类对象,即向上造型)
封装子类中的重复内容(成员变量和方法)
定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的(子类需要实现此抽象方法)

2. 接口

定义接口
  接口可以看成是特殊的抽象类。即:只包含抽象方法和常量的抽象类。通过interface关键字来定义接口。

实现接口
  与继承不同,一个类可以实现多个接口,实现的接口直接用逗号分隔,该类需要实现这些接口中定义的所有方法。通过implements关键字实现接口。接口可以作为一种类型声明变量,一个接口类型的变量可以引用实现了该接口的类的对象,通过该变量可以调用该接口中定义的方法(具体的实现类提供了方法的实现)。一个接口类型变量,引用了子类的对象,调用时,调用的是子类对象的具体的实现。

接口的继承
  接口间可以存在继承关系,一个接口可以通过extends关键字继承另外一个接口,子接口继承了父接口中定义的所有方法
  
接口和抽象类的区别
一个类只能继承一个抽象类,但可以实现多个接口
抽象类中可以包含抽象方法和非抽象方法,而接口中的所有方法均为抽象的
子类继承抽象类必须实现抽象类中所有抽象方法,否则子类也必须是抽象类。而子类实现接口则必须实现接口中所有的抽象方法。

3.内部类
内部类

内部类
在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。

1.成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:

class Circle {
double radius = 0;

public Circle(double radius) {
    this.radius = radius;
}
 
class Draw {     //内部类
    public void drawSahpe() {
        System.out.println("drawshape");
    }
}

}

2.局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

class People{
public People() {

}

}

class Man{
public Man(){

}
 
public People getWoman(){
    class Woman extends People{   //局部内部类
        int age =0;
    }
    return new Woman();
}

}

注意: 局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。

3.匿名内部类
匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护

4.静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

八.异常

异常

异常实现及分类
在这里插入图片描述
1.所有的异常都是从Throwable继承而来的,是所有异常的共同祖先
2.Throwable有两个子类,Error和Exception。
3.Exception,是另外一个非常重要的异常子类。
4.Checked Exception,可检查的异常
5.Unchecked Exception,RuntimeException及其子类都是unchecked exception。

异常的处理
1.通过try…catch语句块来处理:

try
{
// 程序代码
}catch(ExceptionName e1)
{
//Catch 块
}

2.另外,也可以在具体位置不处理,直接抛出,通过throws/throw到上层再进行处理

import java.io.*;
public class className
{
public void deposit(double amount) throws RemoteException
{
// Method implementation
throw new RemoteException();
}
//Remainder of class definition
}

3.finally关键字
finally 关键字用来创建在 try 代码块后面执行的代码块。
无论是否发生异常,finally 代码块中的代码总会被执行。
在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
finally 代码块出现在 catch 代码块最后,语法如下:

try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}

九.正则表达式

详述
概念
正则表达式(Regular Expression)是用于描述一组字符串特征的模式,用来匹配特定的字符串。通过特殊字符+普通字符来进行模式描述,从而达到文本匹配目的工具。
正则表达式目前被集成到了各种文本编辑器/文本处理工具当中

应用场景
(1)验证:表单提交时,进行用户名密码的验证。
(2)查找:从大量信息中快速提取指定内容,在一批url中,查找指定url。
(3)替换:将指定格式的文本进行正则匹配查找,找到之后进行特定替换。

基本要素
(1)字符类
(2)数量限定符
(3)位置限定符
(4)特殊符号

十.Lambda表达式

详解
Lambda简介
Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。

对接口的要求
虽然使用 Lambda 表达式可以对某些接口进行简单的实现,但并不是所有的接口都可以使用 Lambda 表达式来实现。Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法
jdk 8 中有另一个新特性:default, 被 default 修饰的方法会有默认实现,不是必须被实现的方法,所以不影响 Lambda 表达式的使用。

十一.线程

详解

线程的定义
一个程序中不同的分支进行执行

Synchronize线程同步
概念:线程同步指的是,即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作。
多线程访问同一个资源会产生线程安全问题,所以需要进行加锁。

偏向锁、自旋锁、重量级锁
Java在使用synchronize关键字,首先在Java对象头进行markword,记录这个线程id,只有一个线程对这个对象加锁,这个锁叫做偏向锁。
偏向锁如果有线程争用,那么升级为自旋锁?一个锁如果被使用,那么另外一个线程打算争抢这把锁,则会陷入while循环,形成自旋。这叫做自旋锁。
旋10次之后,升级为重量级锁。重量级锁以OS为主体。那么重量级锁不会占用CPU。

注:锁不能降级

乐观锁和悲观锁,公平锁与非公平锁,重入锁

乐观锁
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

悲观锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。

公平锁:加锁之前先检查是否有排队等待的线程,有的话优先处理排前面的线程,先来先得。

非公平锁:线程加锁时直接尝试获取,获取不到就到队尾等待

//非公平锁
Lock nonFairLock=new ReentrantLock(true);//默认空参是true
//公平锁
Lock fairLock=new ReentrantLock(false);

注:非公平锁比公平锁快很多

重入锁
ReetranLock含义是重入锁,什么意思呢,可以进行加锁多次,和解锁多次,比如

public class NoVisibility{
public static void main(String[] args){
Lock lock=new ReentrantLock();
lock.lock();
lock.lock();
lock.unlock();
lock.unlock();
}
}

以上整合内容仅供学习使用,转载地址已一一备注

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值