欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 并发篇复习

并发篇复习

2025/2/24 11:12:12 来源:https://blog.csdn.net/Hgg657046415/article/details/145731646  浏览:    关键词:并发篇复习

文章目录

    • java 并发篇
      • 1. 进程和线程的区别
      • 2. 如何开启线程
        • 2.1 继承(extends)Thread 重写(@Overried)run方法
        • 2.2 实现(Implement)Runnable 接口 实现(@Override)run方法
        • 2.3 实现(Implement)Callable接口,实现(@Override)call方法,通过FutureTask创建一个线程,获取线程返回值
        • 2.4 通过线程池开启
        • 2.5 为什么有这么多种线程开启方式
      • 3 怎么保证线程安全
        • 3.1 为什么需要?
        • 3.2 怎么保证?
        • 3.3 加锁的方式
      • 4 Volatile 和 Synchronized 有什么区别?Volatile能不能保证线程安全?DCL(Double check Lock)单例为什么要加Volatile?
      • 5. JAVA线程锁机制是怎么的?偏向锁,轻量级锁,重量级锁有什么区别?锁机制是怎么升级的?
      • 6. 谈谈你对AQS的理解。以及AQS是如何实现可重入锁的?
      • 7. 有A,B,C三个线程。如何保证三个线程同步执行?如何保证三个线程在并发下依次执行?如何保证三个线程有序交错执行?
      • 8. 如何将一个int数组快速进行排序

java 并发篇

1. 进程和线程的区别

进程(Process):
进程是程序的一次执行实例,是系统进行资源分配和调度的基本单位。它包含了程序运行所需的所有资源,如内存空间、文件句柄、设备资源等。进程之间是相对独立的,每个进程都有自己独立的地址空间。
线程(Thread):
线程是进程中的一个执行单元,是操作系统能够进行运算调度的最小单位一个进程可以包含多个线程,这些线程共享进程的资源(如内存空间),但每个线程有自己的执行栈和程序计数器,可以独立执行任务。

2. 如何开启线程

2.1 继承(extends)Thread 重写(@Overried)run方法
public class MyThread extends Thread{@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println("继承Therad");}}
}public static void main(String[] args){MyThread thread = new MyThread();thread.start;
//.start 启动线程 在start方法里会去调用run方法
//这里如果直接调用run方法,那就不会开启新的线程,只是普通方法的调用
}
2.2 实现(Implement)Runnable 接口 实现(@Override)run方法
public class Runnable01 implements Runnable{@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println("实现Runnable01");}}
}public static void main(String[] args){//实现Runnable接口Thread thread2 = new Thread(new Runnable01());thread2.start();
}
2.3 实现(Implement)Callable接口,实现(@Override)call方法,通过FutureTask创建一个线程,获取线程返回值
public class Callabled01 implements Callable {@Overridepublic String call() throws Exception {return "Callabled01";}
}public static void main(String[] args){//如果需要拿到线程执行过程的放回值 采用事项Callable接口FutureTask<String> futureTask = new FutureTask<>(new Callabled01());Thread  thread4 = new Thread(futureTask);thread4.start();String s = null;try {s = futureTask.get();} catch (InterruptedException e) {} catch (ExecutionException e) {throw new RuntimeException(e);}System.out.println("拿到了"+s);
}
2.4 通过线程池开启

。。。。待补充

2.5 为什么有这么多种线程开启方式

基于java 单继承 可多实现的特性进行设计,根据业务需求自行选择,如果你这个类还要实现其他接口的功能,那么就选择实现(Implement)Runnable 接口

如果有获取线程返回值的需求,可以实现(Implement)Callable接口 实现call方法 的方式

3 怎么保证线程安全

3.1 为什么需要?

当你有多个线程对同一个资源进行操作时,就需要保证线程的安全。

3.2 怎么保证?

加锁,假设我有一段代码(资源)很多线程来抢,就在对这段代码加锁,哪个线程拿到锁了,就可以执行这段代码

3.3 加锁的方式
  1. JVM提供的 Synchronized 关键字 (jdk1.5之前为重量级锁 1.5之后 转化为轻量)

  2. jdk 提供的各种锁 Lock(公平锁 非公平锁 可重入锁)

4 Volatile 和 Synchronized 有什么区别?Volatile能不能保证线程安全?DCL(Double check Lock)单例为什么要加Volatile?

  1. Synchronized 关键字用来加锁,Volatile 只是保持线程之间变量的可见性。通常适用于一个线程写,多个线程读的情况
  2. 不能,Volatile 只能保证线程可见性,不能保证原子性

保证原子可见性,下图为一个主线程,还有两个子线程,子线程的flag是从主线程同步过来的,要使不同子线程之间flag改变是同步的是已知的,就要使用Volatile
在这里插入图片描述
3. Volatile 防止指令重排。在DCL中,防止高并发下的指令重排导致的线程安全问题。

public class SingleDemo01 {//单例模式--懒汉式public static volatile SingleDemo01 instance;private SingleDemo01(){};public static SingleDemo01 getInstance(){if (null == instance){synchronized (SingleDemo01.class){if (null == instance){instance = new SingleDemo01();}}}return instance;}
}

重排序,指的是计算机优化的计算过程,把本来 1 2 3的流程,进行1 3 2这样执行,单线程的情况下不会收到影响,但是多线程情况下,会有问题,volatile 可以禁止重排序的出现,让cpu严格按照 1 2 3 这样执行。
在这里插入图片描述

5. JAVA线程锁机制是怎么的?偏向锁,轻量级锁,重量级锁有什么区别?锁机制是怎么升级的?

  1. java的锁其实就是对象的MarkWord中记录的一个锁状态。无锁,偏向锁,轻量级锁,重量级锁代表不同的锁状态。
  2. 从无锁 --> 偏向锁 --> 轻量级锁 --> 重量级锁 代表锁的升级(偏向锁以及轻量级锁都是JVM级别 重量级锁是操作系统级别)
  3. 锁升级的过程
    在这里插入图片描述

6. 谈谈你对AQS的理解。以及AQS是如何实现可重入锁的?

AQS 是 Java 并发包(java.util.concurrent)的核心框架之一,用于构建锁和其他同步器的基础组件。它通过一个整型状态变量 state 和一个 FIFO (先进先出)的双向队列(CLH 队列变种)来管理线程的同步状态。

  1. AQS是java线程同步的框架。是JDK中很多锁工具的核心实现框架。
  2. 在AQS中维护了一个信号state和一个线程组成的双向链表队列。其中,这个线程队列就是用来给线程排队的。而不同的同步器对 state 的语义有不同的定义,
    例如:
    (1)在 ReentrantLock 中,state 表示锁的重入次数。
    (2)在 Semaphore 中,state 表示剩余的许可证数量。

7. 有A,B,C三个线程。如何保证三个线程同步执行?如何保证三个线程在并发下依次执行?如何保证三个线程有序交错执行?

  1. CountDownLatch
  2. CylicBarrier
  3. Semaphore

8. 如何将一个int数组快速进行排序

  1. 快速排序算发
  2. Fork-Jion 框架
  3. 快速排序算个发+fork-join

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词