IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java知识点梳理-高级部分 -> 正文阅读

[Java知识库]Java知识点梳理-高级部分


前言


一、多线程

1、并行与并发

  • 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
  • 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。

2、线程状态

在这里插入图片描述
线程在Running的过程中可能会遇到阻塞(Blocked)情况:

  • 调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
  • 调用wait(),使该线程处于等待池(wait blocked pool),直notify()/notifyAll(),线程被唤醒被放到锁定池(lock blocked pool),释放同步锁使线程回到可运行状态(Runnable);
  • 对Running状态的线程加同步锁(Synchronized)使其进入(lock blocked pool
    ),同步锁被释放进入可运行状态(Runnable)。

3、基本线程类

基本线程类指的是Thread类,Runnable接口,Callable接口。

Thread 类实现了Runnable接口,启动一个线程的方法:

MyThread my = new MyThread();
  my.start();

Thread类相关方法:

//当前线程可转让cpu控制权,让别的就绪状态线程运行(切换)
public static Thread.yield() 
//暂停一段时间
public static Thread.sleep()  
//在一个线程中调用other.join(),将等待other执行完后才继续本线程。    
public join()
//后两个函数皆可以被打断
public interrupte()

**关于中断:**它并不像stop方法那样会中断一个正在运行的线程。线程会不时地检测中断标识位,以判断线程是否应该被中断(中断标识值是否为true)。终端只会影响到wait状态、sleep状态和join状态。被打断的线程会抛出InterruptedException。
Thread.interrupted()检查当前线程是否发生中断,返回boolean
synchronized在获锁的过程中是不能被中断的。

中断是一个状态!interrupt()方法只是将这个状态置为true而已。所以说正常运行的程序不去检测状态,就不会终止,而wait等阻塞方法会去检查并抛出异常。如果在正常运行的程序中添加while(!Thread.interrupted()) ,则同样可以在中断后离开代码体

Thread类最佳实践:
写的时候最好要设置线程名称 Thread.name,并设置线程组 ThreadGroup,目的是方便管理。在出现问题的时候,打印线程栈 (jstack -pid) 一眼就可以看出是哪个线程出的问题,这个线程是干什么的。

如何获取线程中的异常

在这里插入图片描述
不能用try,catch来获取线程中的异常

  • Runnable

与Thread类似

  • Callable

future模式:并发模式的一种,可以有两种形式,即无阻塞和阻塞,分别是isDone和get。其中Future对象用来存放该线程的返回值以及状态

ExecutorService e = Executors.newFixedThreadPool(3);
 //submit方法有多重参数版本,及支持callable也能够支持runnable接口类型.
Future future = e.submit(new myCallable());
future.isDone() //return true,false 无阻塞
future.get() // return 返回值,阻塞直到该线程运行结束

4、高级多线程控制类

4.1 ThreadLocal类

用处:保存线程的独立变量。对一个线程类(继承自Thread)
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。常用于用户登录控制,如记录session信息。

实现:每个Thread都持有一个TreadLocalMap类型的变量(该类是一个轻量级的Map,功能与map一样,区别是桶里放的是entry而不是entry的链表。功能还是一个map。)以本身为key,以目标为value。
主要方法是get()和set(T a),set之后在map里维护一个threadLocal -> a,get时将a返回。ThreadLocal是一个特殊的容器。

ThreadLocal的内存泄露原因
由于Thread中包含变量ThreadLocalMap,因此ThreadLocalMap与Thread的生命周期是一样长,如果都没有手动删除对应key,都会导致内存泄漏。

但是使用弱引用可以多一层保障:弱引用ThreadLocal不会内存泄漏,对应的value在下一次ThreadLocalMap调用set(),get(),remove()的时候会被清除。

因此,ThreadLocal内存泄漏的根源是:由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄漏,而不是因为弱引用。
ThreadLocal正确的使用方法
每次使用完ThreadLocal都调用它的remove()方法清除数据
将ThreadLocal变量定义成private static,这样就一直存在ThreadLocal的强引用,也就能保证任何时候都能通过ThreadLocal的弱引用访问到Entry的value值,进而清除掉 。

4.2 原子类

常用原子类:

AtomicBooleanAtomicIndtegerAutomicLong  元老级的原子更新,方法几乎一模一样
 DoubleAdderLongAdderDoubleLong的原子更新性能进行优化提升
 DoubleAccumulatorLongAccumlator 支持自定义运算

原子更新数组类型

AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray

原子的更新属性

  原子的更新某个类里的字段时,需要使用原子更新字段类,AtomicStampedReferenceAtomicReferenceFiledUpdater

参阅:https://blog.csdn.net/sinat_36265222/article/details/86636949
https://blog.csdn.net/weixin_38003389/article/details/88569336

4.3 Lock类

使用ReentrantLock实现同步

class MyThread implements Runnable {
    private int ticket = 10;
    private Lock lock = new ReentrantLock();

    public void run() {
        //获取对象锁
        try {
            while (this.ticket > 0) {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "还有" + this.ticket-- + "张票");
                lock.unlock();       //释放对象锁
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }
        } finally {
        }
    }
    
}

测试:

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        Thread thread = new Thread(myThread, "黄牛A");
        Thread thread1 = new Thread(myThread, "黄牛B");
        Thread thread2 = new Thread(myThread, "黄牛C");
        thread.start();
        thread1.start();
        thread2.start();
    }

}

使用Condition实现等待/通知

5、容器类

5.1 BlockingQueue

阻塞队列。该类是java.util.concurrent包下的重要类,通过对Queue的学习可以得知,这个queue是单向队列,可以在队列头添加元素和在队尾删除或取出元素。类似于一个管道,特别适用于先进先出策略的一些应用场景。
在这里插入图片描述

常见的阻塞队列有:

ArrayListBlockingQueue
LinkedListBlockingQueue
DelayQueue
SynchronousQueue

LinkedBlockingQueue
1、读写锁分开,性能较 ArrayListBlockingQueue 只有一把锁控制读写要高一些。
2、无界队列,不会触发Reject异常,ArrayListBlockingQueue初始化时必须指定宽度。SynchronousQueue的容量只有1。

ArrayListBlockingQueue
1、读写一把锁,在大并发的消费者和生产者场景中,性能较LinkedBlockingQueue差一些。
2、有界队列,会触发Reject异常,在增加队列和删除队列元素时,不会产生额外的数据(数组特性),GC影响比LinkedBlockingQueue更小

SynchronousQueue

1、可以理解为容量为1的阻塞队列,只有被消费了,才能接受生产者的消息。
2、当线程池的线程数已经达到了maxiumSize时,新增加时出发Reject异常
3、有公平策略和不公平策略,对应到不同进出算法 - FIFO,LIFO。

场景归类

无界的消息任务,读写频繁,使用LinkedBlockingQueue
有界的,对GC影响较小,读写不过于频繁的场景,使用ArrayListBlockingQueue
只有一个生产者和消费者,需要使用不同的公平策略的场景,使用 SynchronousQueue

生产者-消费者 简单示例:
package container;

import java.util.Random;
import java.util.concurrent.BlockingQueue;

/**
 * TODO:
 *
 * @Version 1.0
 * @Author HJL
 * @Date 2021/12/19 23:11
 */
//生产者
public class Producer implements Runnable {
    private final BlockingQueue<Integer> blockingQueue;
    private Random random;

    public Producer(BlockingQueue<Integer> blockingQueue) {
        this.blockingQueue = blockingQueue;
        random = new Random();

    }

    public void run() {
        while (true) {
            int info = random.nextInt(100);
            try {
                boolean result = blockingQueue.offer(info);
                System.out.println("生产:" + info + (result? " 成功":"失败!"));
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
/**
 * TODO:
 *
 * @Version 1.0
 * @Author HJL
 * @Date 2021/12/19 23:11
 */
//消费者
public class Consumer implements Runnable{
    private final BlockingQueue<Integer> blockingQueue;
    public Consumer(BlockingQueue<Integer> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }
    public void run() {
        while(true){
            Integer info;
            try {
                info = blockingQueue.poll(100, TimeUnit.MILLISECONDS);
                if(null == info) {
                    System.err.println("当前商品紧缺!");
                }else {
                    System.out.println("消费:" + info);
                }
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
public class QueueTest {
    public static void main(String[] args) {
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue(100);
        Consumer consumer = new Consumer(blockingQueue);
        Producer producer = new Producer(blockingQueue);
        Thread thread = new Thread(consumer);
        Thread thread1 = new Thread(producer);
        thread.start();
        thread1.start();

    }
}

TimeUnit 使用
主要作用

  • 时间颗粒度转换
  • 延时

常用的颗粒度

TimeUnit.DAYS          //天
TimeUnit.HOURS         //小时
TimeUnit.MINUTES       //分钟
TimeUnit.SECONDS       //秒
TimeUnit.MILLISECONDS  //毫秒

1、时间颗粒度转换

public long toMillis(long d)    //转化成毫秒
    public long toSeconds(long d)  //转化成秒
    public long toMinutes(long d)  //转化成分钟
    public long toHours(long d)    //转化成小时
    public long toDays(long d)     //转化天

5.2 ConcurrentHashMap

在JDK1.7中ConcurrentHashMap采用了数组+Segment+分段锁的方式实现。
在这里插入图片描述
JDK8中ConcurrentHashMap参考了JDK8 HashMap的实现,采用了数组+链表+红黑树的实现方式来设计,内部大量采用CAS操作。并发控制使?synchronized 和 CAS 来操作。

在这里插入图片描述
ConcurrentHashMap不论1.7还是1.8,他的执行效率都比HashTable要高的多,主要原因还是因为Hash Table使用了一种全表加锁的方式。
在这里插入图片描述

6、管理类

6.1 ThreadPoolExecutor

ExecutorService e = Executors.newCachedThreadPool();
ExecutorService e = Executors.newSingleThreadExecutor();
ExecutorService e = Executors.newFixedThreadPool(3);
// 第一种是可变大小线程池,按照任务数来分配线程,
// 第二种是单线程池,相当于FixedThreadPool(1)
// 第三种是固定大小线程池。
// 然后运行
e.execute(new MyRunnableImpl());

二、反射

1、反射机制的功能

Java反射机制主要提供了以下功能:

在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具有的成员变量和方法。
在运行时调用任意一个对象的方法。
生成动态代理。

2、 实现反射机制的类

Java中主要由以下的类来实现Java反射机制(这些类都位于java.lang.reflect包中):

Class类:代表一个类。 Field类:代表类的成员变量(成员变量也称为类的属性)。
有三种方式可以获得类的Class对象实例:

1、Object的getClass()方法

// 创建对象,通过对象的getClass()方法获取Class对象实例
Class clazz = new HelloWorld().getClass();

2、类型的.class

// 通过类型的class获得Class实例
Class clazz = HelloWorld.class;

3、Class.forName(“类的完全限定名”)


	// 通过Class.forName("类的完全限定名")获取Class对象实例
	try {
	    Class clazz = Class.forName("com.learn.demo.reflection.HelloWorld");
	} catch (ClassNotFoundException e) {
	    e.printStackTrace();
	}

Method类:代表类的方法。

// 获得类的public成员方法
        Method[] methods0 = clazz.getMethods();

Constructor类:代表类的构造方法。

 // 构造方法-一个int类型参数的构造方法
 Constructor constructor0 = clazz.getConstructor(int.class);
  Object obj0 = constructor0.newInstance(1);

  // 构造方法-一个int类型参数和一个String类型参数的构造方法
  Constructor constructor1 = clazz.getConstructor(int.class, String.class);
  Object obj1 = constructor1.newInstance(2, "我出生了!");

获得类的成员变量

  // 通过getDeclaredFields方法获取private成员变量
        Field [] fields = clazz.getDeclaredFields();

Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

//利用Array.newInstance创建一维数组
int rows = 3;
int cols = 2;
Integer[] array = (Integer[]) Array.newInstance(Integer.class,rows);
 Array.set(array,0,110);
 
//利用Array.newInstance创建多维数组
Double[][] arraymn = (Double[][]) Array.newInstance(Double.class,rows,cols);
Array.set(arraymn[0],0,1D);

三、IO流

在这里插入图片描述
在这里插入图片描述
具体参阅:https://www.cnblogs.com/wugongzi/p/12092326.html

四、网络编程

1、网络协议

在这里插入图片描述
在这里插入图片描述
TCP三次握手过程:
在这里插入图片描述

TCP四次挥手过程:
在这里插入图片描述
TCP与UDP的区别

  1. TCP基于连接,UDP是无连接的;
  2. 对系统资源的要求,TCP较多,UDP较少;
  3. UDP程序结构较简单;
  4. TCP是流模式,而UDP是数据报模式;
  5. TCP保证数据正确性,而UDP可能丢包;TCP保证数据顺序,而UDP不保证;

2、Socket整体流程

在这里插入图片描述

总结

此处记录自己在重温java知识点中的部分重点纪要,对java中的高级基础知识点作一个概括性梳理,铸就更扎实的基础。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-23 15:37:37  更:2021-12-23 15:38:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:00:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码