博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第八天并发编程篇
阅读量:38364 次
发布时间:2022-02-15

本文共 2728 字,大约阅读时间需要 9 分钟。

一、简述线程、进程、程序的基本概念?

1.进程: 我们把运行中的程序叫做进程,每个进程都会占用内存与CPU资源,进程与进程之间互相独立.
2.线程: 线程就是进程中的一个执行单元,负责当前进程中程序的执行。一个进程可以包含多个线程。多线程可以提高程序的并行运行效率。
3.程序:是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。

二、创建线程的几种方法

1.继承Thread类
2.实现Runnable接口
3.实现Callable接口

三、线程有什么优缺点?

优点:

1. 在多核CPU中,通过并行计算提高程序性能. 比如一个方法的执行比较耗时,现在把这个方法逻辑拆分,分为若干个线程并发执行,提高程序效率。
2. 可以解决网络等待、io响应导致的耗时问题。
3. 提高CPU的使用率.提高网络资源的利用率

缺点:

1. 线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
2. 线程之间对共享资源的访问会造成资源安全问题;
3. 多线程存在上下文切换问题CPU 通过时间片分配算法来循环执行任务,所以本身就会占用cpu资源

四、start 和 run 方法有什么区别?

调用start方法方可启动线程,而run方法只是thread类中的一个普通方法调用,还是在主线程里执行。

五、可以直接调用Thread类的run()方法吗

可以直接调用,但是只是执行了一个普通的run方法而已,并没有真正的启动线程

六、Thread类的 sleep 方法和对象的 wait 方法都可以让线程暂停执行,它们有什么区别?

1、方法归属不同
sleep()方法是属于Thread类中的,而wait()方法,则是属于Object类中的。

2、sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程,当指定的时间到了又会自动恢复运行状态。

所以在调用sleep()方法的过程中,线程不会释放对象锁。

3、调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,

只有针对此对象调用notify()方法后该线程才准备获取对象锁进入运行状态。
七、notify 和 notifyAll 有什么区别?
notify方法只能唤醒一个线程,notifyall可以唤醒所有线程,通常与wait()方法搭配使用。

七、sleep、join、yield 方法有什么区别?

1.sleep是暂停当前线程,把cpu的给其他线程使用

2.join是当前线程等待指定的线程执行完成。
如果线程A执行了线程B的join()方法,并且线程B还没有执行完成,线程A将会被阻塞,直到线程B执行完成。
3.yield
thread.yield()  让CPU的时间片,尽量切换其他线程去执行,但不会释放它持有的锁

八、线程的生命周期(状态)

1.新建状态
2.就绪状态
3.阻塞状态
4.等待状态
5.死亡状态

九、Java关键字volatile作用

1、保证变量的可见性
当一个变量被声明为volatile时,它的值会被存储在主内存中,而不是线程的本地内存中。
每次读取该变量时,都会从主内存中读取最新的值
2、防止指令重排序
在多线程并发下,线程之间是通过主内存来共享数据的,
当一个线程修改了某个变量的值时,这个新值会被写入该线程的本地内存,并不会立即写入主内存。
如果没有使用volatile关键字来修饰该变量,其他线程可能无法及时看到这个变量的最新值,从而导致并发问题。
十、为什么代码会重排序?
提高效率
为了提高程序的执行效率,编译器和CPU都可能会对程序进行指令重排序。
指令重排序是指在不改变程序执行结果的前提下,重新安排指令的执行顺序,以提高程序的执行效率。
十一、Java关键字synchronized作用以及原理?

1.Java关键字synchronized是用于实现多线程同步的机制,确保多个线程在访问共享资源时不会产生竞争和冲突,从而避免数据不一致的情况。

其主要原理是基于Java对象的内部锁,即监视器锁(Monitor Lock),确保在同一时刻只有一个线程可以访问被保护的代码块或方法。

2.当一个线程尝试获取被synchronized关键字保护的资源时,

如果该资源已被其他线程占用,该线程就会进入等待状态。
当占用资源的线程释放该资源时,等待队列中的线程会竞争获取该资源,
并且只有一个线程会成功获取到该资源,其他线程继续等待。

3.synchronized关键字保证了可见性和原子性,可见性是通过JVM底层的内存屏障来实现的,原子性则是通过监视器锁的互斥性来实现的。

在synchronized块内,线程获得了锁,它将会清空工作内存,从而使得该线程使用的变量能够从主内存中重新读取,同时也会把工作内存中的变量写回到主内存中。
这样,其他线程就可以读取到最新的值,从而保证了可见性。

十二、请你描述一下怎么使用lock锁的?
Lock lock  = new ReentrantLock();
try{
      lock.lock();
//可能会出现线程安全的操作
  }finally{
    //尽量在finally中释放锁
    
    lock.unlock();
  }
十三、Lock和synchronized区别

1.语法层面:

1.1.synchronized是关键字,源码在jvm中,用c++ 语言实现

1.2.Lock 是接口,源码由jdk 提供,用java语言实现

1.3.使用 synchronized 时,退出同步代码块锁会由jvm自动释放,而使用Lock时,需要手动调用unlock方法释放锁

,否则可能会导致死锁等问题

2.功能层面

相同点:
2.1都可以用来控制多个线程访问共享资源的互斥性。
2.2都支持可重入锁机制,即同一个线程在已经获得锁的情况下能够再次获取该锁。
2.3都支持在发生异常或者代码执行完毕时自动释放锁资源,避免死锁等问题。
不同点:
2.4 Lock 提供了更多的锁机制选择,例如公平锁、非公平锁、可重入锁、读写锁等多种类型;而 synchronized 只有一种类型,即独占锁(排他锁)。
2.5 Lock 应该优先考虑在高并发场景下使用,可以获得更好的性能和灵活性;而 synchronized 关键字则更适合用于简单的线程同步场景,易于使用和维护

十四、线程池的优点
1. 避免创建线程和销毁线程的性能开销
2. 提高响应速度
3. 线程池的线程可以重复使用

十五、什么是死锁?

死锁就是两个或两个以上的线程被无限的阻塞,线程之间相互等待所需资源。

十六、线程池的执行流程

 

转载地址:http://uxvduy.baihongyu.com/

你可能感兴趣的文章
linux 下配置 redis开机自动启动
查看>>
css使用百比分来控制图片的显示
查看>>
php-cgi.sock failed (13: Permission denied)
查看>>
小程序的按需登录的实现代码及思想
查看>>
让swoole支持异步redis的编辑安装
查看>>
微信支付退款成功回调结果的解密
查看>>
解决正式服和测试服两个各自争抢小程序的 access_token的问题
查看>>
Delphi10 编写的ActiveX Server没有自动注册的问题
查看>>
BOF 或 EOF 中有一个是“真”,或者当前的记录已被删除,所需的操作要求一个当前的记录。
查看>>
在CentOS7下安装Angular
查看>>
CentOS7下安装rabbitMQ的简单方法
查看>>
Centos7安装多个版本nodejs
查看>>
Delphi10.2开发兼容JAVA的MD5程序
查看>>
MySQL并发获取自增值的测试及处理
查看>>
MySQL修改密码的旧办法与新办法
查看>>
Docker的Debian容器不支持汉字的问题
查看>>
临时或长期修改VIM配色方案
查看>>
Debian 10 容器玩转composer
查看>>
在Debian、CentOS下安装swoole
查看>>
docker.io/nginx 修改apt源后提示Certificate verification failed: The certificate is NOT trusted.
查看>>