目录:

1.并行和并发:

2.进程和线程:

3.创建多线程的方式:

4.接口和继承多线程的区别:

5.callable和runnable的区别:

6.线程的生命周期:

7.线程死亡状态:

8.线程安全问题:

9.解决线程安全问题方法:

10.同步代码块和同步方法和同步锁:

11.公平锁和非公平锁:

12.synchronized和lock的区别:

13.死锁:

14.死锁的4个条件:

15.死锁预防:

16.线程间通讯:

17.Threadlocal:

18.可重入锁和不可重入锁:

19.同步容器和并发容器:

20.多线程的优点和缺点:

21.线程池的优点:

22.线程池核心参数:

23.并发编程常见的三个问题:

24.java内存模型:

25.synchronized的特性:

1.并行和并发:

并行:多个线程在同一时间点发生。

并发:多个线程在同一个时间段发生。

2.进程和线程:

进程:应用程序的运行。

线程:进程的单位。

3.创建多线程的方式:

1.继承thread类。

2.实现runnable接口。

3.实现callable接口。

4.使用线程池。

4.接口和继承多线程的区别:

1.接口避免了java单继承带来的局限性。

2.线程池只支持接口的方式。

5.callable和runnable的区别:

相同点:callable和runnable都是使用接口创建多线程。

不同点:callable需要重写call方法,runnable需要重写run方法。

callable需要处理异常,runnable不需要处理异常。

callable有返回值,runnable没有返回值。

callable可以中断,runnable不能中断。

6.线程的生命周期:

1.新建状态:new出来的时候。

2.就绪状态:调用start方法。

3.运行状态:cpu调度。

4.阻塞状态:调用wait,sleep,或join方法,同步阻塞,获取其他线程锁定的对象。

5.死亡状态:线程运行结束等情况。

7.线程死亡状态:

1.run方法结束。

2.线程出现异常。

3.调用stop方法。

8.线程安全问题:

多线程安全主要由全局变量或静态变量引起。一旦操作全局变量或静态变量,则可能引发线程的安全性问题。

9.解决线程安全问题方法:

1.synchronized关键字

2.同步锁lock

3.volatile关键字修饰全局变量或静态变量。

4.局部变量threadlocal

10.同步代码块和同步方法和同步锁:

同步代码块:synchronized修饰一段代码块,需要锁定一个对象。

同步方法:synchronized修饰方法,锁定的对象为类本身。

同步锁:new一个lock对象,在需要同步的代码中先加锁,再使用try catch包住同步的内容,最后再finally中解锁。

11.公平锁和非公平锁:

公平锁:按线程的先来后到的顺序依次获取锁。

非公平锁:多个线程可以同时抢占锁。

12.synchronized和lock的区别:

synchronized是一个关键字,可以修饰代码块和方法,发生异常会自动释放锁,不可中断。

lock是一个接口,发生异常不会释放锁,所以需要再finally中手动释放锁,可以中途中断。

13.死锁:

多个线程因为争夺资源,而造成的一种相互等待的现象,无外力作用下,无法继续推动。此时不会发生异常,而是所有的线程都处于阻塞的状态。

14.死锁的4个条件:

1.互斥条件:当一个线程获取锁后,不允许其他线程锁定。

2.不可剥夺条件:锁定的对象,无法被强制剥夺。

3.请求保持:线程获取锁后,除非运行完毕,否则不会释放锁。

4.循环等待:多个线程锁定对象后,等待其他线程获取的资源释放。

15.死锁预防:

1.避免多次锁定,即锁定一个对象后,再锁定第二对象,释放之前锁定的对象。

2.设定锁的超时时间。

3.使多个线程有相同的加锁顺序。

16.线程间通讯:

正常来说多线程是由cpu随机调配执行,当我们想让多线程按照我们预想的方式执行,则需要使用线程间通讯。

1.休眠唤醒:调用wait方法后,线程休眠,但必须使用notify来唤醒。

Object:wait、notify、notifyall

Condition: condition、signal、signalall

2.countdownlatch:使一个线程等待其他线程执行完毕后,再执行。

3.cyclicbarrier:一组线程等待某个状态后,一起执行。

17.Threadlocal:

threadlocal提供了线程的局部变量。即相同的变量由每一个线程单独维护。和synchronized相似避免了多个线程访问相同的变量是,造成的访问冲突。

synchronized牺牲了时间来保证变量访问的冲突。

threadlocal因为每一个线程都有单独的局部变量,所以牺牲了空间来保证变量访问的冲突。

使用方法:new一个threadlocal对象后,调用get和set方法即可。

18.可重入锁和不可重入锁:

可重入锁:线程可以拿到自己锁定的对象,但解锁的时候,锁定几次就需要解锁几次。

不可重入锁:线程不能拿到自己锁定的对象,会发生阻塞。

19.同步容器和并发容器:

同步容器:victor,hashtable.

并发容器:currenthashmap

20.多线程的优点和缺点:

多线程优点:提高资源利用率,提升程序的执行效率。

多线程缺点:创建和销毁线程浪费资源,线程间的切换同样浪费资源。

21.线程池的优点:

1.减少了线程的创建和销毁,节约资源。

2.避免高访问量是,创建大量的线程,造成资源不足。

22.线程池核心参数:

核心线程数:线程池创建时创建的线程数,这些线程不会被销毁。

最大线程数:线程池所能创建的最大线程数。

阻塞队列:核心线程满后,多余的请求放在阻塞队列中。

空闲线程存活时间:核心线程和阻塞队列满后,额外创建的线程存活的时间。

handle:当最大线程数也满了的时候,所采取的策略。(1.直接抛异常,2.谁提交谁执行,3.抛弃队列中等待的任务,4.抛弃当前任务)

23.常用的4个线程池:

1.newCachedThreadPool:核心线程数为0。有新任务时,会自动创建线程。

2.newFixedThreadPool :核心线程数和最大线程数相同,即最多创建的线程数就是核心线程数。多余的线程交给队列。

3.newSingleThreadExecutor :线程数量始终只有一个,保证了队列的先进先出。

4.newScheduledThreadPool:支持定时或周期性的任务。

23.并发编程常见的三个问题:

1.可见性:

当一个线程对共享变量的值进行修改后,其他的线程无法立即查看更新的值。

2.原子性:

当一个线程对共享变量操作到一半时,另外的线程也可能操作该变量,干扰了前一个线程的执行,例如i++;

3.有序性:

程序中代码的执行顺序,并不一定是按照开发者编写的代码的顺序。

java常用synchronized关键字来保证这三大特性。

24.java内存模型:

java内存模型是一套规范,描述了共享变量的访问规则,java内存模型是对共享数据的可见性,原子性,有序性的规则和保障。

25.synchronized的特性:

1.可重入特性:一个线程可以重复进入synchronized,重复获取同一把锁。原理是内部有一个计数器会记录获取几次数。

2.不可中断特性:一个线程获取锁后,另一个线程想要获取锁,必须等待,如果第一个线程不释放锁,第二个线程会一直等待。

26.CAS:

CAS:compare and Swap,比较相同再交换。CAS可以保证共享变量赋值时的原子操作。当多个线程cas更新同一个变量时,只有一个能成功,其他的全部失败,失败的线程可以再次尝试更新。CAS属于乐观锁,即每次拿数据都认为不会修改,有人修改了就重试。

旧值和内存中的值和新值:比较内存中的值和旧值是否相同,相同则替换成新值。

ABA问题:线程一从内存中取出变量A,线程二同样从内存中取出A,并将A的值替换成B之后,又重新赋值为A,此时线程一再从内存中拿到变量A,发现没变化,误认为还是原来的A,操作成功。例如别人挪用资金后,趁你没发现又还了回来,表面上没影响,实际可能出现大问题。解决方式是使用AtomicStampedReference类来解决,具体就是加版本号,每操作一次就加上版本号。

最后修改:2022 年 02 月 10 日
如果觉得我的文章对你有用,请随意赞赏