并行
1、并发 vs 并行
并发: 同一时间段,多个任务都在执行 (单位时间内不一定同时执行);指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。
并行: 单位时间内,多个任务同时执行。指在同一时刻,有多条指令在多个处理器上同时执行
2、死锁:
多个线程因争夺资源而相互等待的现象。
死锁条件:
互斥条件:该资源任意一个时刻只由一个线程占用。
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件:线程已获得的资源在末使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
3、sleep() wait() notify() notifyAll()
sleep(ong mili):没有释放锁,会自动苏醒
wait(long mili):自动苏醒 + notify/notifyAll()
wait():需要别的线程调用同一个对象的notify和notifyAll()
4、start vs run:
start启动线程并使线程进入就绪状态,然后自动调用run开始运行
单独执行run,不能启动线程,只能想main里的执行函数一样。
5、单例
public class Singleton{
public volatile static Singleton uniqueInstance; //防止JVM指令重排
Singleton(){};
public Singletion getUniqueInstance(){
if (uniqueInstance == null){
synchronized (Singletion.class){
if (uniqueInstance == null){
uniqueInstance = new Singletom();
}
}
}
return uniqueInstance;
}
}
6、synchronized 底层
monitorenter:同步代码块第一行(获取锁 + 1)
monitorexit:同步代码块最后于行(锁计数设为0)
7、synchronized关键字最主要的三种使用方式:
- 修饰实例方法: 作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁
- 修饰静态方法: 也就是给当前类加锁,会作用于类的所有对象实例,因为静态成员不属于任何一个实例对象,是类成员( static 表明这是该类的一个静态资源,不管new了多少个对象,只有一份)。所以如果一个线程 A 调用一个实例对象的非静态 synchronized 方法,而线程 B 需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象锁。
- 修饰代码块: 指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
8、线程创建
继承Tread类:
class MyThread extends Thread{ @Override public void run(){} } MyThread my = new MyThread(); my.start();
实现Runable接口
public class MyRunable implements Runable{ @Override public void run(){} } Runable runable = new MyRunable(); Thread thread = new Thead(runable); thread.start();
9、volatile 最轻量级的同步机制
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。在变量读取前从主内存刷新变量值,在新值能立即同步到主内存中
2)禁止进行指令重排序。
java的主内存和工作内存:
主内存:存放变量
工作内存:优先存储于寄存器和高速缓存中,每个线程都有自己的工作内存,保存了被该线程使用到的变量的主内存副本拷贝
主内存于工作内存之间的问题:缓存一致性

浙公网安备 33010602011771号