Java内存模型

Java内存模型中规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存(可以与前面将的处理器的高速缓存类比),线程的工作内存中保存了该线程使用到的变量到主内存副本拷贝,线程对变量的所有操作(读取、赋值)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要在主内存来完成,线程、主内存和工作内存的交互关系。
Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样底层细节。此处的变量与Java编程时所说的变量不一样,指包括了实例字段、静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,后者是线程私有的,不会被共享。
结论:线程之间的通信必须经过主内存。
volatile
volatile关键字可以使多线程操作统一变量时对其他线程可见(通知其他线程)
volatile不具有原子性
wait()与notify()、notifyAll()
wait()与notify()、notifyAll()方法,Objec类就有该三个方法,所以任何类都有该三个方法。
他们只能在线程同步下使用(synchroized),而且是同一个锁的资源(synchroized的锁)
obj.wait():释放ogj的锁使当前线程处于阻塞状态,等待唤醒(notify()、notifyAll())
obj.notify():唤醒其他一个调用obj.wait()被阻塞的线程(等待队列中的第一个线程)(不会通知优先级比较高的线程)
obj.notifyAll():唤醒其他全部 调用obj.wait()被阻塞的线程(也不会按照线程的优先级来执行)
sleep()和 wait()
wait()一定要在线程同步下使用,sleep()不需要
wait()会释放锁,sleep()不会
sleep()当时间到了线程就会进入就绪状态,wait()必须要等待notify()或.notifyAll()唤醒才会进入就绪状态
Lock锁
用法
Lock lock =new ReentrantLock();//加入到锁的对象中(obj)
obj.lock.lock();//上锁,线程中使用
try{
//可能会出现线程安全的操作
}finally{
//一定在finally中释放锁
//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
obj.lock.ublock();//释放锁,线程中使用
}
与synchronized的区别
Lock 接口可以尝试非阻塞地获取锁当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。
Lock接口能被中断地获取锁 与 synchronized 不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。
Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。
Condition用法
Condition的功能类似于在传统的线程技术中的,Object.wait()和Object.notify()的功能。
Condition condition = lock.newCondition();//线程中使用
res. condition.await(); 类似wait
res. Condition. Signal() 类似notify
停止线程
1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
3. 使用interrupt方法中断线程。
什么是ThreadLoca
ThreadLocal提高一个线程的局部变量,访问某个线程拥有自己局部变量。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
原理:
使用了map
Map(Thread.currentThread,值);
网友评论