前言
谈到并发你想到的是什么?高效?多线程?锁?锁优化?并发究竟是什么,在并发系列博客中一探究竟吧。
优缺点
优点
- 充分利用CPU
- 适合复杂业务,方便业务拆分
缺点
频繁上下文切换
- 解决方案
- 1.使用最少线程
- 2.无锁并发编程,如concurrHashMap分段锁
- 3.CAS算法乐观锁
- 4.使用协程
线程安全,死锁
- 解决方案
- 1.避免一个线程获得多个锁
- 2.避免一个线程占有多个资源
- 3.使用定时锁
- 4.使用数据库锁,加锁解锁在一个连接里,避免解锁失败=
易混淆概念
同步vs异步
- 同步:前面的方法执行完了后面的方法才可以执行
- 异步:前面的方法没有执行完,后面就可以执行
并发vs并行
- 并发:多个任务交替进行,单cpu,多线程
- 并行:多个任务同时进行,多cpu
线程的状态和基本操作
如何新建线程
三种方法:1.thread类 2.runnable接口 3.callable接口
public class CreateThreadDemo {
public static void main(String[] args) {
//1.继承Thread
Thread thread = new Thread() {
@Override
public void run() {
System.out.println("继承Thread");
super.run();
}
};
thread.start();
//2.实现runable接口
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("实现runable接口");
}
});
thread1.start();
//3.实现callable接口
ExecutorService service = Executors.newSingleThreadExecutor();
Future<String> future = service.submit(new Callable() {
@Override
public String call() throws Exception {
return "通过实现Callable接口";
}
});
try {
String result = future.get();
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
线程的状态转换
线程的基本操作
- interrupted
- join
- sleep vs wait
1.sleep是静态方法;wait是实例方法
2.sleep退出cpu,不释放对象锁; wait让出cpu外还要释放锁 - sleep vs yield
1.sleep,yield都是让出cpu时间片,但是sleep是所有线程都可以竞争cpu,而yield是只有优先级相同的线程可以竞争
守护线程
- 守护线程如垃圾回收线程,JIT线程
- 用户线程退出,守护线程也退出
- 守护线程不一定执行finally里的代码
- 用thread.setDaemon(true)来设置守护线程
小结
为什么有并发,线程的状态转换,那些操作实现状态转换等是并发的基础。下一篇将从并发理论入手,涉及javaJMM内存模型,重排序,happensbefore原则。