Java并发编程——线程间通信:Synchronized与Monitor

volatile

关键字volatile可以修饰字段,就是告知程序任何对该变量的访问都需要先从共享内存中获取,而对它的改变必须同步刷新回共享内存,它能保证所有线程对变量访问的可见性。
但是过多的使用,会降低程序执行的效率。

总线风暴

由volatile关键字修饰的变量在工作内存和主内存产生大量交互(无效交互),会产生大量无效工作内存变量,(嗅探机制)造成总线带宽被占用,导致有效内容延迟响应,这就产生总线风暴。
解决办法一般是加锁(synchronized)

synchronized与Monitor

synchronized

synchronized可以修饰方法或者以同步块的形式来进行使用,他主要确保多个线程在同一时刻,只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性。
任意一个对象都有自己的监视器,当这个对象由同步块或者这个对象的同步方法调用时,执行方法的线程必须先获取该对象的监视器才能进入同步块或者同步方法中,而没有获取监视器的线程将会被阻塞在同步块和同步方法的入口,进入BLOCKED状态。
在这里插入图片描述任何线程对Object的访问,首先就是要获取Object监视器。
如果获取失败,线程进入同步队列,线程状态变为BLOCKED.
当同样访问Object的前驱(线程)释放了锁,则该释放release操作唤醒在同步队列中处在BLOCKED状态的线程节点,使其重新尝试对监视器的获取。

等待通知机制

是指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用了对象O的notify()方法,线程A收到通知后从对象O的wait()方法返回,进而执行后续操作。
通过对象O来完成通信。

Thread.join()

当线程A等待thread线程终止之后才从thread.join()返回。
当线程终止时,会调用线程自身的notifyAll()方法,会通知所有等待在该线程对象上的线程。

ThreadLocal 与内存泄漏

ThreadLocal是线程变量,是一个以ThreadLocal对象为key,任意对象值为value的存储结构。这个结构附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值。

 static class ThreadLocalMap {

        /**
         * The entries in this hash map extend WeakReference, using
         * its main ref field as the key (which is always a
         * ThreadLocal object).  Note that null keys (i.e. entry.get()
         * == null) mean that the key is no longer referenced, so the
         * entry can be expunged from table.  Such entries are referred to
         * as "stale entries" in the code that follows.
         */
        static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
            //这里的super是创建一个弱引用
                super(k);
                value = v;
            }
        }

static class ThreadLocalMap
static class Entry extends WeakReference<ThreadLocal<?>>,在ThreadLocal中,所采用的存储数据结构,是ThreadLocalMap。而组成Map的结构是Entry,而且这里的Entry是弱引用。
在JVM中,有四种对象的引用方式——强引用,软引用,弱引用,虚引用。
在GC中,对四种引用有不同的回收方式。
强引用:任何情况下,只要强引用在,对象就不会被收集。
软引用:在系统发生OOM前,会把这些对象列入回收范围之内,进行二次回收。
弱引用:当GC开始,无论内存是否足够,都会回收只被弱引用关联的对象。
虚引用:为一个对象设置虚引用的唯一目的就是在这个对象被回收时能收到一个系统通知。

key是指向ThreadLocal类型变量的弱引用,value是指向任意对象值的强引用。
在这里插入图片描述key——ThreadLocal实例
key持有的是弱引用,而当ThreadLocal外部的强引用 tl 被回收时,key就会变成null。但是ThreadLocalMap仍然存在,并没有被回收,所以value就一直存在。当产生大量entry对象之后,同时ThreadLocalMap又没有被完全回收,value的数量会越来越多,这就会造成内存泄漏。
使用ThreadLocal.remove()可以防止内存泄漏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值