目录:
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类来解决,具体就是加版本号,每操作一次就加上版本号。