线程的基础知识
线程与进程的区别



并行与并发的区别


线程创建方式
继承Thread类
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class MyThread extends Thread { @Override public void run() { } public static void main(String[] args) { MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.start(); t2.start(); } }
|
实现Runnable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class MyRunnable implements Runnable { @Override public void run() { } public static void main(String[] args) { MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); t1.start(); t2.start(); } }
|
实现Callable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class MyCallable implements Callable<String> { @Override public String call() throws Exception { return "ok"; } public static void main(String[] args) { MyCallable mc = new MyCallable(); FutureTask<String> ft = new FutureTask<String>(mc); Thread t1 = new Thread(ft); t1.start(); String res = ft.get(); System.out.println(res); } }
|
线程池创建线程
1 2 3 4 5 6 7 8 9 10 11 12
| public class MyExecutors implements Runnable { @Override public void run() { } public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(3); threadPool.submit(new MyExecutors()); threadPool.shutdown(); } }
|


线程状态

线程顺序执行

Java中的wait和sleep方法的不同

如何停止一个正在运行的线程

线程中并发安全
synchronized原理

Monitor

第二个monitorexit是为了防止同步代码块发生异常时能正常释放锁

每个Java对象都可以关联一个Monitor对象,如果使用synchronized给对象上锁(重量级)后,该对象头的Mark Word中就被设置指向Monitor对象的指针
对象的内存结构

MarkWord

重量级锁

轻量级锁


偏向锁


JMM
Java内存模型(与JVM中的Java内存结构区分)

CAS



乐观锁和悲观锁

volatile



volatile使用技巧:
AQS




ReentrantLock的实现原理


synchronized和Lock的区别

死锁
互斥
持有且等待
不可剥夺
循环依赖


ConcurrentHashMap


Java如何保证并发安全

-
synchronized:同步加锁
-
JUC提供的lock锁:加锁


线程池
核心参数


常见阻塞队列


如何确定核心线程数

线程池种类




为什么不建议使用Executors创建线程池

使用场景
线程池使用场景





如何控制某个方法允许并发访问线程的数量


ThreadLocal




