b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

Java多线程核心知识点的整理

电脑杂谈  发布时间:2020-06-06 14:09:31  来源:网络整理

java多线程避免死锁_java如何避免死锁_java线程死锁例子

1. 并发编程的三个要素?

1)原子性

原子性是指一项或多项操作,要么全部执行且在执行过程中不被其他操作中断,要么根本不执行.

2)可见性

可见性意味着当多个线程对一个共享变量进行操作时,一个线程修改了该变量后,其他线程可以立即看到修改的结果.

如何获得可见性:

同步或锁定: 确保只有一个线程同时获取锁定执行代码. 在释放锁之前,最新值将刷新到主存储器以实现可见性.

3)秩序

已排序,即程序的执行顺序是根据代码的顺序执行的.

2. 多线程的价值?

1)利用多核CPU

多线程可以真正发挥多核CPU的优势,达到充分利用CPU的目的,通过多线程同时完成几件事而不会互相干扰.

2)防止阻塞

从程序运行效率的角度来看,单核CPU不仅不利用多线程,而且由于在单核CPU上运行多个线程而导致线程上下文切换,从而降低了整体效率该程序. 但是对于单核CPU,我们仍然需要应用多线程,以防止阻塞. 想象一下,如果单核CPU使用单个线程,只要该线程被阻塞,就可以说要远程读取某些数据,对等端没有返回并且没有设置超时时间,那么整个程序将在数据返回. 停止运行. 多线程可以防止此问题. 多个线程同时运行,即使一个线程的代码执行被阻止读取数据,也不会影响其他任务的执行.

3)易于建模

这是另一个没有明显优势的优势. 假设有一个很大的任务A,是单线程编程,那么有必要考虑很多,并且建立整个程序模型很麻烦. 但是,如果我们将这个大任务A分解为几个小任务,即任务B,任务C和任务D,构建程序模型并通过多线程分别运行这些任务,那么它将更加简单.

3. 创建线程的方法是什么?

1)继承Thread类以创建线程类

2)通过Runnable接口创建线程类

3)通过Callable and Future创建一个线程

4. 三种创建线程的方式比较?

1)通过实现Runnable和Callable接口来创建多线程.

优点是:

线程类仅实现Runnable接口或Callable接口,并且还可以继承其他类.

这样,多个线程可以共享同一个目标对象,因此非常适合多个相同的线程处理相同的资源情况,以便可以将CPU,代码和数据分离以形成清晰的模型. 面向对象思维的很好体现.

缺点是:

编程稍微复杂一些. 如果要访问当前线程,则必须使用Thread.currentThread()方法.

2)通过继承Thread类创建多个线程

优点是:

编写起来很简单. 如果需要访问当前线程,则不需要使用Thread.currentThread()方法,可以直接使用它来获取当前线程.

缺点是:

Thread类继承了Thread类,因此无法继承其他父类.

3)Runnable和Callable之间的区别

5. 线程状态流程图

线程生命周期和五个基本状态:

Java线程具有五个基本状态

java如何避免死锁_java线程死锁例子_java多线程避免死锁

1)新建状态(新建): 创建线程对象对时,它将进入新状态,例如: 线程t = new MyThread();

2)就绪状态(可运行): 调用线程对象的start()方法(t.start();)时,线程进入就绪状态. 处于就绪状态的线程仅表示该线程已准备就绪,可以随时等待CPU调度执行,而不是意味着该线程将在执行t.start()之后立即执行;

3)运行状态: 当CPU开始将线程调度为就绪状态时,此时可以实际执行该线程,即进入运行状态. 注意: 就绪状态是进入运行状态的唯一入口点,也就是说,如果线程要进入运行状态以执行,则必须首先处于就绪状态; <​​/ p>

4)阻塞(Blocked): 处于运行状态的线程出于某种原因暂时放弃使用CPU的权利并停止执行. 此时,它进入阻塞状态,直到进入就绪状态,才有机会重新进入. 由CPU调用以进入运行状态. 根据阻塞的不同原因,阻塞状态可以分为三种类型:

1. 等待阻塞: 处于运行状态的线程执行wait()方法使线程进入等待阻塞状态; <​​/ p>

2. 同步阻塞—线程无法获取同步锁(由于该锁已被其他线程占用),它将进入同步阻塞状态; <​​/ p>

3. 其他阻塞—通过调用线程的sleep()或join()或发出I / O请求java多线程避免死锁,线程将进入阻塞状态. 当sleep()状态超时,join()等待线程终止或超时或I / O处理完成时,线程将重新进入就绪状态.

5)死状态: 由于异常,线程完成执行或退出run()方法,并且线程结束其生命周期.

6. 什么是线程池?有哪些创建方法?

线程池用于预先创建几个线程. 如果有要处理的任务,则线程池中的线程将处理该任务. 处理之后,该线程将不会被销毁,而是等待下一个任务. 因为创建和销毁线程会消耗系统资源,所以当您要频繁创建和销毁线程时,可以考虑使用线程池来提高系统性能.

java提供了用于创建线程池的java.util.concurrent.Executor接口的实现.

创建四个线程池:

(1)newCachedThreadPool创建一个可缓存的线程池

(2)newFixedThreadPool创建一个固定长度的线程池来控制并发线程的最大数量.

(3)newScheduledThreadPool创建一个固定长度的线程池,该池支持计划的和定期的任务执行.

(4)newSingleThreadExecutor创建一个单线程线程池,它将仅使用单个工作线程来执行任务.

7. 线程池的优点?

1)重用现有线程以减少对象创建和销毁的开销.

2)可以有效控制并发线程的最大数量,提高系统资源的利用率,避免过多的资源竞争和阻塞.

3)提供诸如定期执行,定期执行,单线程和并发编号控制之类的功能.

8. Java中的同步收集和并发收集有什么区别?

同步收集类:

并发收集类:

9. 同步集和并发集的区别

同步集合和并发集合都为多线程和并发提供了合适的线程安全集合,但是并发集合具有更高的可伸缩性. 同步收集比并发收集要慢得多. 主要原因是锁. 同步集合锁定整个May或List,而并发集合(例如ConcurrentHashMap,

整个Map分为几个片段,只有相关的片段被锁定,同时允许多个线程访问其他未锁定的片段(红色和黑色的树被添加到JDK1.8版本的底部).

10. 常用的并发工具是什么?

11. CyclicBarrier和CountDownLatch的应用场景?

CountDownLatch: 一个线程(或多个线程),等待另外N个线程完成某些操作,然后才能执行该操作. CyclicBarrier: N个线程互相等待. 在任何线程完成之前,所有线程必须等待.

CountdownLatch使用方案:

在某些应用程序中,您需要先等待某个条件满足要求,然后才能执行后一件事情;同时,当线程完成时,也将触发该事件以便执行后续操作,这时您可以使用CountDownLatch.

CyclicBarrier使用场景

CyclicBarrier可以用于多线程计算数据中,并最终合并应用场景的计算结果.

12. CyclicBarrier和CountDownLatch之间的区别

1)CountDownLatch仅仅意味着一个线程等待,直到它等待的其他线程完成,并且调用countDown()方法发出通知,当前线程可以继续执行.

2)CyclicBarrier是所有线程都等待,直到所有线程准备好进入await()方法,所有线程才同时开始执行!

3)CountDownLatch的计数器只能使用一次. 可以使用reset()方法重置CyclicBarrier计数器. 因此CyclicBarrier可以处理更复杂的业务场景,例如,如果计算错误,则可以重置计数器并让线程再次执行.

java如何避免死锁_java线程死锁例子_java多线程避免死锁

4)CyclicBarrier还提供了其他有用的方法,例如getNumberWaiting方法来获取被CyclicBarrier阻塞的线程数. isBroken方法用于了解阻塞的线程是否被中断. 如果被中断,则返回true,否则返回false.

13. 同步的作用是什么?

在Java中,synced关键字用于控制线程同步,即在多线程环境中,同步代码段不能同时由多个线程执行.

可以将同步添加到一段代码或方法中.

14. 易失性关键字的作用

对于可见性,Java提供了volatile关键字以确保可见性.

当共享变量被volatile修改时,它将确保修改后的值将立即更新到主内存中,而当需要读取其他线程时,它将去内存中读取新值.

从实践的角度来看,挥发物的重要作用是与CAS结合以确保原子性. 有关详细信息,请参见java.util.concurrent.atomic包下的类,例如AtomicInteger.

15. 什么是CAS

CAS是比较和交换的缩写,这就是我们所说的比较交换.

cas是基于锁的操作,并且是乐观锁. 在Java中,锁分为乐观锁和悲观锁. 悲观锁会锁定资源,并等待先前获得该锁的线程释放该锁,然后下一个线程才能访问它. 乐观锁定采取宽泛的态度java多线程避免死锁,并以某种方式处理资源而不进行锁定,例如通过向记录添加版本来获取数据. 与悲观锁定相比,性能得到了大大提高.

CAS

该操作包含三个操作数-

存储位置(V),预期原始值(A)和新值(B). 如果内存地址中的值与A中的值相同,则将内存中的值更新为B. CAS通过无限循环获取数据. 如果在第一轮循环中,线程a所获取的地址中的值被线程b所修改,则线程a需要旋转,并且直到下一个周期才可能执行它.

java.util.concurrent.atomic包下的类主要使用CAS操作(AtomicInteger,AtomicBoolean,AtomicLong)实现.

16. CAS问题

1)CAS很容易引起ABA问题. 线程a将值更改为b,然后将其更改为a. 目前,CAS认为没有任何变化,但实际上已经发生了变化. 可以通过版本号标识此问题的解决方案,并且每个操作的版本都增加1. . 在java5中,提供了AtomicStampedReference来解决该问题.

2)无法保证代码块的原子性

由CAS机制保证的变量原子操作的知识不能保证整个代码块的原子性. 例如,如果您需要确保自动更新这三个变量,则必须使用synced.

3)CAS导致CPU利用率增加. 我之前说过,CAS中有一个循环判断过程. 如果线程尚未获得状态,则将始终占用CPU资源.

17. 什么是未来?

在并发编程中,我们经常使用非阻塞模型. 在多线程的先前三个实现中,无论是继承线程类还是实现可运行接口,都不能保证将获得先前的执行结果. 通过实现Callback接口并使用Future,您可以接收多个线程的执行结果.

将来表示可能尚未完成的异步任务的结果. 任务成功或失败之后,可以在此结果中添加回调以进行相应的操作.

18. 什么是AQS

AQS是AbustactQueuedSynchronizer的缩写. 它是Java改进的低级同步工具类. 它使用int类型的变量指示同步状态,并提供一系列CAS操作来管理此同步状态.

AQS是用于构建锁和同步器的框架. 使用AQS可以轻松高效地构造大量广泛使用的同步器,例如ReentrantLock,Semaphore和其他诸如ReentrantReadWriteLock,SynchronousQueue和FutureTask. 等等都是基于AQS.

AQS支持两种同步方法:

1. 独家

2. 共享

这对用户实现不同类型的同步组件非常方便,例如,排他类型(例如ReentrantLock),共享类型(例如Semaphore,CountDownLatch)以及组合类型(例如ReentrantReadWriteLock). 简而言之,AQS提供了使用的基础支持,用户可以自由发挥如何组装和实现它.

19. 什么是ReadWriteLock

首先,请澄清一下. 不是说ReentrantLock不好. 如果使用ReentrantLock,则可能是防止线程A写入数据而线程B读取数据而导致的数据不一致,但是以这种方式,如果线程C正在读取数据而线程D也正在读取数据,则读取数据不会改变数据,无需锁定,但仍处于锁定状态,从而降低了程序的性能.

因此,ReadWriteLock诞生了. ReadWriteLock是一个读写锁接口,ReentrantReadWriteLock是ReadWriteLock接口的特定实现,它实现了读写分离,共享读锁,写锁是互斥的,读写不会互斥,读写,写作和阅读,写作和写作是互斥的,从而提高了阅读和写作的性能.

20. 什么是FutureTask

如前所述,FutureTask代表异步计算任务. 可以将具体的Callable实现类传递到FutureTask中,该类可以等待此异步操作任务的结果获得,判断它是否已完成,取消任务和其他操作. 当然,由于FutureTask也是Runnable接口的实现类,因此FutureTask也可以放入线程池中.

21. 同步和ReentrantLock之间的区别

Synchronized是相同的关键字,就好像ReentrantLock是一个类一样,这是两者之间的本质区别. 由于ReentrantLock是一个类,因此它提供的功能比同步功能越来越多. 它可以被继承,可以具有方法,并可以具有各种类变量. ReentrantLock比同步的可伸缩性体现在以下几点: <


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-236046-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...