java基础知识--02

java基础知识

树越要往上长,它的根,越是要往下扎。
共勉!


synchronized
1、synchronized修饰代码块
2、synchronized修饰类的普通方法
3、synchronized修饰类的静态方法

重量级锁锁对象的原理(初学者的理解,可能有误):

在这里插入图片描述

修饰理解:

1、synchronized修饰代码块

同步语句块的实现使用的是monitorenter 和 monitorexit 指令。


2、synchronized修饰类的普通方法

锁的是这个对象。如对象多个普通方法被修饰,同一个对象访问这些方法时,公用一个锁。访问其他没有被synchronized修饰的普通方法,不受锁约束。
不同对象的锁不同,互不影响


3、synchronized修饰类的静态方法

锁是类锁(.class)。这个范围就比对象锁大。这里就算是不同对象,但是只要是该类的对象,就使用的是同一把锁。多个线程调用该类的同步的静态方法时,都会阻塞。



四种锁:

偏向锁
如果一个线程获得了锁,那么锁就进入偏向模式。

 

轻量级锁
倘若偏向锁失败,虚拟机并不会立即升级为重量级锁,它还会尝试使用一种称为轻量级锁的优化手段(1.6之后加入的)。线程运行到安全点后,对象的Mark Word 的结构转为轻量级锁,原持有线程的的锁信息也跟着升级为轻量级锁,与原线程竞争的外来线程进入自旋。

 

自旋锁
轻量级锁失败后,虚拟机为了避免线程真实地在操作系统层面挂起,还会进行一项称为自旋锁的优化手段。

 

重量级锁
如果锁竞争情况严重,某个达到最大自旋次数的线程,会将轻量级锁升级为重量级锁(依然是CAS修改锁标志位,但不修改持有锁的线程ID)。

 

锁消除
编译时去除不可能存在共享资源竞争的锁,如StringbBuffer自动转为StringBuilder

 

参考连接0:
https://blog.csdn.net/qq_40949465/article/details/88734834

参考连接1:
https://www.cnblogs.com/xiaolovewei/p/9152718.html

自旋锁:
https://www.jianshu.com/p/9d3660ad4358?utm_source=oschina-app

锁是什么: https://zhuanlan.zhihu.com/p/71156910


HTTP和HTTPS

https是在http基础上加上安全传输协议,加上SSL/TLS,http常用端口80,https是443
SSL(Secure Sockets Layer、安全套接层协议)
TLS(Transport Layer Security、安全传输层协议),是SSL 3.0的后续版本

原理流程:
1、服务器端存在公钥和私钥,浏览器请求服务器,服务器返回公钥
2、浏览器生成随机密钥 A
3、用服务器给的公钥,加密(非对称)A,传给服务器
4、服务器用私钥解密(非对称)A
5、至此,浏览器、服务器都有明文的 A,后续通讯信息,都用A来对称加密

 

参考连接:
https://blog.csdn.net/liuxingrong666/article/details/83869161



单例模式

一个类只允许有一个实例
构造函数私有化,对外暴露一个获取对象的接口,在类中创建唯一的一个静态实例对象。

破坏单例模式:

序列化后反系列化

反射

clone

防止破坏单例模式:
1、防止反射

定义一个全局变量,当第二次调用构造方法时抛出异常

2、防止克隆破坏

重写clone(),直接返回单例对象

3、防止序列化破坏

添加readResolve(),返回Object对象。

当JVM从内存中反序列化地"组装"一个新对象时,就会自动调用这个 readResolve方法来返回我们指定好的对象了, 单例规则也就得到了保证

参考连接0:
https://blog.csdn.net/fd2025/article/details/79711198

参考连接1:
https://blog.csdn.net/fd2025/article/details/79711198


泛型

概念:泛型是一个未知的数据类型

E e:Element 元素,E通常用来表示集合类型中的元素类型
T t: 是一个泛型,传递什么类型,就返回什么类型

1、 定义在类上:public class className < T > { }

在类上定义的泛型,在类的普通方法中也可以使用,但是类方法中的静态方法不能使用,这也很好理解,静态方法不需要实例化也能直接使用,然而还未实例化之前,谁也不知道是什么类型,故不能在静态方法中使用。

2、定义在方法上:public static final < T > void methodName(T t){ }
留个疑问,为什么类中的泛型声明是在类名字后面,而方法的泛型声明是在返回类型前面?都放在名字后面不好吗。。。
泛型是先定义,后使用的。放在返回类型,是为了适应这种情况:
public static final < T > T methodName(T t){ }

3、泛型类派生子类
子类明确要使用什么类型的情况下,继承泛型类:
public class ChildClass extends ParentClass< String > { }

子类不明确要使用什么类型的情况下,继承泛型类:
public class ChildClass< T > extends ParentClass< T > { }

其实也没什么区别,你也可以这么写:
public class ChildClass< Integer> extends ParentClass< Integer> { }

通配符 ? :
不常用通配符,对通配符感悟不深。感觉使用了通配符反而不灵活了。
如果要使用通配符,则是配合PECS原则来限制集合的读取写入。


PECS原则(Producer Extends Consumer Super):

PE:
如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer Extends)

/**
 * Created by HXH on 2021/3/18
 * @desc
 */
public class TestPECS {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();//String集合
        List<? extends Object> list1 = list;
        for (Object s : list1){
            //可以读取,因为不管是什么子集,都有Object类型帮它兜底,总是可以转化成功
        }

        //不能加入,虽然Integer是Object子类
        //list1只知道类型上限是Object,却不知具体是什么类型,不能由父类转子类
        //通俗一点的理解:可以看到list最先是List<String>类型,这里是Integer类型
        list1.add(new Integer(1));//报错
        
        list1.remove(0);//可以删除
    }
}

CS:
如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super)

        //能操作下限类
        List<Object> objectList = new ArrayList<>();
        List<? super String> list = objectList;
        list.add("555");//可以
        list.add(new Object());//不行

        //能操作下限类的子类
        List<Number> numberList = new ArrayList<>();
        List<? super Number> list2 = numberList;
        list2.add(2f);//可以
        list2.remove(3L);//可以
        
       //读取
        for (Number n : list2){
            //不行
        }
        for (Object n : list2){
            //只能用Object接收
        }

参考连接0:
https://segmentfault.com/a/1190000014120746

参考连接1:
https://blog.51cto.com/flyingcat2013/1616068


 
posted @ 2021-10-05 21:13  q彩虹海q  阅读(36)  评论(0)    收藏  举报