layout: post title: "多线程和高并发" subtitle: " "mutil thread and high concurrent"" date: 2018-10-07 06:00:00 author: "青乡" header-img: "img/post-bg-2015.jpg" catalog: true tags: - multi thread
什么是死锁?死锁是怎么发生的?
1.2个线程
2.2个锁对象
每个线程各自拥有一个锁对象,同时,每个线程还要去获取另外一个锁对象,但是这个锁对象已经被对方线程占有。
写一个死锁的代码?
锁对象1
锁对象2
方法1(){
synchronized(锁对象1){
synchronized(锁对象2){
...
}
}
}
方法2(){
synchronized(锁对象2){
synchronized(锁对象1){
...
}
}
}
为什么会出现数据不同步的情况?
1.因为会使用多线程。 2.多线程会导致数据一致性的问题。
为什么要同步?
解决数据一致性的问题。
进程、线程
1.进程 与线程的关系 包含多个线程。
访问数据 不同进程是不同的地址空间。即不同进程里的数据互相不能访问。
那不同进程如何通信? ?
2.线程 与进程的关系 属于进程。 一个进程一般是一个应用程序,一个应用程序要完成多个任务,就会出现多线程。这是多线程最大的作用。
访问数据 共用同一个进程空间(即内存),所以会导致数据不一致。这是最大的问题。
如何解决数据不一致的问题? 基本上所有的技术都是在解决这个问题。
线程的状态
1.新建 new Thread();
2.在运行 Thread.start();
3.睡眠/阻塞 .sleep();
IO阻塞; //本地数据访问、网络数据访问,都会出现访问数据阻塞,例如,数据量太大,网络不好。
4.再次运行 睡醒了;
IO完毕。
5.结束/死亡 代码运行完毕。
怎么同步
有2种方法, 1.基础 即常用方法。
一般使用同步关键字,同步方法或代码块。
2.提高 jdk 线程池。
jdk 高级并发类。
以上都是属于jdk并发包的内容。
怎么使用?
底层原理?
java并发包
线程池
并发集合和映射
显式锁
优点
1.显式锁
2.可以控制同步粒度
还有优点
1.中断
2.超时
并发原子
参考
1.官方文档 docs.oracle.com/javase/tuto…
1)讲并发的有一本书 很好 看那一本书就够
2)还有一本是jdk 并发包 作者写的
3.再结合google 和 维基百科
happen-before
?
指令重排序
就是多线程的代码没有先后顺序,完全随机。
代码
package gzh.test.multiThread;
/**
* 启动程序
*
* ---
* 如何才能乱序输出?
* 调试的时候,在线程1打断点,就会先执行线程2的任务。
* @author gongzhihao
*
*/
public class MultiThreadTest {
static Data d = new Data();
public static void main(String[] args) {
//初始数据
System.out.println("a=" + d.a + ", flag=" + d.flag);
System.out.println();
//多线程访问数据
// for (int i = 0; i < 10; i++) {
// Thread t1 = new Thread(new TaskThread1());
// t1.start();
// }
Thread t1 = new Thread(new TaskThread1());
t1.start();
Thread t2 = new Thread(new TaskThread2());
t2.start();
}
}
package gzh.test.multiThread;
/**
* 任务线程
* @author gongzhihao
*
*/
public class TaskThread1 implements Runnable{
public void run() {
System.out.println("current thread: " + Thread.currentThread() + ", MultiThreadTest.d: " + MultiThreadTest.d);
MultiThreadTest.d.writer();
}
}
package gzh.test.multiThread;
/**
* 任务线程
* @author gongzhihao
*
*/
public class TaskThread2 implements Runnable{
public void run() {
System.out.println("current thread: " + Thread.currentThread() + ", MultiThreadTest.d: " + MultiThreadTest.d);
MultiThreadTest.d.reader();
}
}
package gzh.test.multiThread;
/**
* 数据
* @author gongzhihao
*
*/
class Data {
int a = 0;
boolean flag = false;
public synchronized void writer() {
a = 1;
System.out.println("a=" + a);
flag = true;
System.out.println("flag=" + flag);
}
public synchronized void reader() {
System.out.println("flag=" + flag);
if (flag) {
System.out.println("flag=" + flag);
int i = a;
System.out.println("i=" + i);
}
}
}
输出结果
a=0, flag=false
current thread: Thread[Thread-0,5,main], MultiThreadTest.d: gzh.test.multiThread.Data@67565b6a //看共享数据id,可以看出来是同一个对象67565b6a
current thread: Thread[Thread-1,5,main], MultiThreadTest.d: gzh.test.multiThread.Data@67565b6a
flag=false
a=1
flag=true
线程组ThreadGroup
作用是方便统一管理线程,以及线程的各个特性。
每个线程都属于一个线程组,还有一个父线程组。