Java内存模型

2018-06-15  本文已影响0人  HJJ_3c00

Java内存模型

这里的主内存、工作内存与Java内存区域的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,值);

上一篇 下一篇

猜你喜欢

热点阅读