源码+官方文档 面试高频问!

java.util 工具包、包、分类
业务:普通的线程代码 Thread
Runnable 没有返回值,效率相比于 Callable 相对较低!



    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        /* Notify the group that this thread is about to be started
         * so that it can be added to the group‘s list of threads
         * and the group‘s unstarted count can be decremented. */
        group.add(this);
        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }
	// 本地方法,底层的C++ , java  无法直接操作硬件
    private native void start0();


package com.kuang;
public class demo1 {
    public static void main(String[] args) {
        // 获取cpu的核数
        // CPU 密集型, IO密集型
        System.out.println(Runtime.getRuntime().availableProcessors());
    }
}
并发编程的本质:充分利用CPU的资源
所有的公司都很看重!
企业,挣钱 => 提高效率,裁员,找一个厉害的人顶替三个不怎么样的人;
人员(减),技术成本(高)
public enum State {
    // 新生
    NEW,
    // 运行
    RUNNABLE,
    // 阻塞
    BLOCKED,
    // 等待,死死地等
    WAITING,
    // 超时等待,等不下去了就不等
    TIMED_WAITING,
   // 终止
    TERMINATED;
}
wait/sleep 区别



公平锁:十分公平,可以先来后到
非公平锁:十分不公平,可以插队(默认)
package com.kuang;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SaleTicketDemo {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "A").start();
        new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "B").start();
        new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "C").start();
    }
}
class Ticket {
    private int number = 30;
    Lock lock = new ReentrantLock();
    public void sale() {
        lock.lock();
        try {
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "剩余" + (--number) + "张");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

面试的:单例模式、排序算法、生产者和消费者、死锁
package com.kuang.pc;
public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();
        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}
class Data{
    private int number = 0;
    public synchronized void increament() throws InterruptedException {
        if (number!=0){
            wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        notifyAll();
    }
    public synchronized void decreament() throws InterruptedException {
        if (number==0){
            wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        notifyAll();
    }
}
问题存在,A B C D 4个线程!虚假唤醒

if 改成 while
package com.kuang.pc;
public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();
        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();
        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                    data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"C").start();
        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"D").start();
    }
}
class Data{
    private int number = 0;
    public synchronized void increament() throws InterruptedException {
        while (number!=0){
            wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        notifyAll();
    }
    public synchronized void decreament() throws InterruptedException {
        while (number==0){
            wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        notifyAll();
    }
}

代码实现:
package com.kuang.pc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++)
                    data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "B").start();
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++)
                    data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "C").start();
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "D").start();
    }
}
class Data {
    private int number = 0;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    public  void increament() throws InterruptedException {
        lock.lock();
            try {
                while (number != 0) {
                    condition.await();
                }
                number++;
            System.out.println(Thread.currentThread().getName() + "==>" + number);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public  void decreament() throws InterruptedException {
        lock.lock();
        try {
            while (number == 0) {
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName() + "==>" + number);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
任何一个新的技术,绝对不仅仅是覆盖了原来的技术,一定会有优势和补充!

代码测试:
package com.kuang.pc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            for (int i = 0; i < 10; i++)
               data.printA();
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++)
                data.printB();
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++)
                data.printC();
        }, "C").start();
    }
}
class Data {
    private int number = 1;
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();
    public void printA() {
        lock.lock();
        try {
            while (number!=0){
                condition1.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"=>AAAAAA");
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void printB() {
        lock.lock();
        try {
            while (number!=1){
                condition2.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"=>BBBBBB");
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void printC() {
        lock.lock();
        try {
            while (number!=2){
                condition3.await();
            }
            number=0;
            System.out.println(Thread.currentThread().getName()+"=>CCCCCC");
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
如何判断锁的对象!永远知道什么是锁,锁到底锁的是谁?
对象、Class


hashSet 底层是什么?

回顾Map的基本操作



Callable 和 Runnable 的区别:
代码测试:


package com.kuang;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 适配类
        FutureTask futureTask = new FutureTask(new Callable() {
            @Override
            public Integer call() throws Exception {
                System.out.println("call()");
                return 1024;
            }
        });
        new Thread(futureTask,"A").start();
        new Thread(futureTask,"B").start(); // 结果会被缓存,效率高
        // 获取Callable返回结果并打印
        System.out.println(futureTask.get());
    }
}
细节:

package com.kuang;
import java.util.concurrent.CountDownLatch;
// 计数器
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        //总数是6,必须要执行任务的时候,再使用!
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"Go Out");
                countDownLatch.countDown();// 数量减一
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();// 等待计数器归零,再向下执行
        System.out.println("Close Door");
    }
}


加法计数器
package com.kuang;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println("召唤神龙!");
        });
        for (int i = 1; i <= 7; i++) {
            final int temp = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"收集了"+temp+"颗龙珠");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }
}
Semaphore:信号量

package com.kuang;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
    public static void main(String[] args) {
        //线程数量:停车位!限流!
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                //acquire();得到
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"抢到车位");
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName()+"离开车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
                //release() 释放
            }, String.valueOf(i)).start();
        }
    }
}

ReadWriteLock

package com.kuang;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
 * 独占锁(写锁)  一次只能被一个线程占有
 * 共享锁(读锁)  多个线程可以同时占有
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        for (int i = 1; i <= 10; i++) {
            final int temp = i;
            new Thread(() -> {
                myCache.put(temp+"",temp+"");
            }, String.valueOf(i)).start();
        }
        for (int i = 1; i <= 10; i++) {
            final int temp = i;
            new Thread(() -> {
                myCache.get(temp+"");
            }, String.valueOf(i)).start();
        }
    }
}
class MyCache{
    private volatile Map<String,String> map = new HashMap<>();
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    public void put(String key,String value){
        readWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"写入");
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"写入成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }
    public void get(String key){
        readWriteLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"读取");
            map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }
    }
}

阻塞队列:


BlockingQueue BlockingQueue 不是新的东西




代码略
线程池:三大方法、7大参数、4种拒绝策略


package com.kuang;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo {
    public static void main(String[] args) {
//         Executors.newSingleThreadExecutor();
        ExecutorService threadPool = Executors.newCachedThreadPool();
//       Executors.newFixedThreadPool(3);
        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}
源码探究
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//21亿
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
//本质ThreadPoolExecutor()
public ThreadPoolExecutor(int corePoolSize,//核心线程池大小
                              int maximumPoolSize,//最大核心线程池大小
                              long keepAliveTime,//超时了没有人调用就会释放
                              TimeUnit unit,//超时单位
                              BlockingQueue<Runnable> workQueue,//阻塞队列
                              ThreadFactory threadFactory,//线程工厂,创建线程的,一般不用动
                              RejectedExecutionHandler handler//拒绝策略) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }


package com.kuang;
import java.util.concurrent.*;
public class Demo {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}


了解:IO密集型,CPU密集型(调优)

package com.kuang;
import java.util.concurrent.*;
public class Demo {
    public static void main(String[] args) {
        //CPU密集型
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                Runtime.getRuntime().availableProcessors(),
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}
新时代的程序员:lambda表达式、链式编程、函数式接口、Stream流式计算
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}
//超级多FunctionalInterface
//简化编程模型,在新版本的框架底层大量应用!
//foreach(消费者类的函数式接口)


代码测试:
Function函数式接口








大数据:存储 + 计算
存储:集合、MySQL 本质就是存储东西的
计算都应该交给流来操作!


ForkJoin 在JDK1.7,并行执行任务!提高效率。大数据量!
大数据:Map Reduce(把大任务拆分为小任务)

这里面维护的都是双端队列





测试:





线程 工作内存 主内存
8种操作:


问题:程序不知道主内存的值已经被修改过了


原子性:不可分割
线程A在执行任务的时候,不能被打扰的,也不能被分割。要么同时成功,要么同时失败

如果不加 lock 和 synchronized ,怎么样保证原子性

使用原子类,解决 原子性问题

这些类的底层都直接和操作系统挂钩!在内存中修改值!Unsafe类是一个很特殊的存在!
什么是指令重排:你写的程序,计算机并不是按照你写的那样去执行的。
源代码-->编译器优化的重排-->指令并行也可能重排-->内存系统也会重排-->执行



饿汉式 DCL懒汉式,探究!





枚举类型的最终反编译源码:

大厂你必须要深入研究底层!有所突破!修内功,操作系统,计算机网络原理




CAS:比较当前工作内存中的值和主内存中的值,如果这个值是期望的,那么则执行操作!如果不是就一直循环!
缺点:


带版本号的原子操作!

注意:

非公平锁:非常不公平,可以插队(默认都是非公平)
可重入锁(递归锁)

synchronized版(代码略)
lock版(代码略)
spinlock

自定义的锁

测试:


死锁是什么?

死锁测试,怎么排除死锁:

解决问题:


面试,工作中!排查问题:
原文:https://www.cnblogs.com/ilbty/p/12640015.html