多线程 问答

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

 

posted @ 2023-08-19 15:05  野鹤闲人  阅读(13)  评论(0编辑  收藏  举报