多线程 问答
1、线程的状态或什么周期
新建,就绪,运行,阻塞,销毁
new, runnable,running,blocked,terminated

java角度

2、java里面,wait和 sleep的区别
wait 是object的方法,等待时会释放锁
sleep是 线程Thread的方法,睡眠时不会释放持有的对象锁,需要捕获异常。结束睡眠后,进入 runnable状态。如果线程异常终止,terminated状态
object的 wait,notify,notifyall 用于同步控制
sleep可以在任何地方用
3、进程和线程的区别
进程是最小的资源分配单位,线程是最小的执行单位
4、程序开多少线程合适
2n+1
5、synchronized 和 lock的区别

简述一下sync从偏向锁 升级到到轻量锁的情况
前提:在偏向锁和轻量锁开启的情况下,当线程进入时,首先会加上偏量锁
1、判断是否可偏向的状态:markWord锁标志为 01,是否偏向锁为 1
2、当可偏向,查看线程ID 如果是自己,则执行代码(第5步);否则执行第3步
3、cas竞争锁,如果成功,则记录markword里面的线程ID为自己,执行代码(第5步);否则执行第4步
4、如果cas失败表示有竞争,达到savepoint时,偏向锁线程挂起,升级为轻量锁。 被阻塞在安全点的额线程继续往下执行同步代码???
5、执行代码
6、DCL double check?
if singleton == null
synchronized(singleton.class){
if singleton == null{singleton=new singleton();}
}
7、condition实现阻塞队列,(生产者,消费者)
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ProviderConsumer<T> {
private int length;
private Queue<T> queue;
private ReentrantLock lock=new ReentrantLock();
Condition providerCondition =lock.newCondition();
Condition consumerCondition =lock.newCondition();
private ProviderConsumer(int length){
this.length=length;
queue=new LinkedList<T>();
}
private void add(T product){
lock.lock();
try {
while (queue.size()>=length) {
providerCondition.await();
}
queue.add(product);
consumerCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
private T consume(){
lock.lock();
try {
while(queue.isEmpty()) {
consumerCondition.await();
}
T product=queue.remove();
providerCondition.signal();
return product;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
return null;
}
}
=
8、按顺序打印abc
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class PrintABC {
ReentrantLock lock=new ReentrantLock();
Condition conditionA= lock.newCondition();
Condition conditionB= lock.newCondition();
Condition conditionC= lock.newCondition();
int value=0;
//打印几遍
int count;
private PrintABC(int count){
this.count=count;
}
private void printabc(){
new Thread(new ThreadC()).start();
new Thread(new ThreadB()).start();
new Thread(new ThreadA()).start();
}
public static void main(String[] args) {
PrintABC abc=new PrintABC(2);
abc.printabc();
}
class ThreadA implements Runnable{
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < count; i++) {
while(value%3!=0){
conditionA.await();
}
System.out.println("A");
value++;
conditionB.signal();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}
class ThreadB implements Runnable{
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < count; i++) {
while(value%3!=1){
conditionB.await();
}
System.out.println("B");
value++;
conditionC.signal();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
class ThreadC implements Runnable{
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < count; i++) {
while(value%3!=2){
conditionC.await();
}
System.out.println("C");
value++;
conditionA.signal();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}
9、volatile 的作用和怎么实现的
可见性,防止指令重排序
volatile修饰的变量,修改后可以立即同步到内存;使用前也会从内存刷新。本质上也是通过内存屏障 实现的
store store
volatile 写
store load
load load
volatile 读
load store
9、concurrentHashMap
1.7 是分段锁
1.8 舍弃了分段锁,每次锁住的是 node对象,而不是某一段数组。元素存在Node数组中
我根据原代码
java.util.HashMap#putVal
java.util.concurrent.ConcurrentHashMap#putVal
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
synchronized (f) {
if (tabAt(tab, i) == f) {
10、三个线程,按顺序执行,
join??
join属于强行插队,例如在主线程中,如果子线程.join,让主线程就会让出cpu给子线程
join里面的实现方法,用的是wait,会释放锁。
11、
=
参考地址:
https://blog.csdn.net/Firstlucky77/article/details/125173318
备注:公众号清汤袭人能找到我,那是随笔的地方

浙公网安备 33010602011771号