线程间通信

218 阅读2分钟

一.volatile和synchronize

1.volatile:读取数据时每次都从主内存中读取,每次写数据都要刷新到主内存,保证了数据的可见性和有序性。

2.synchronize:对需要操作的数据进行加锁,保证只有一个线程访问,保证数据的可见性和原子性,但是不保证数据的有序性。

二.等待通知机制
调用此类方法首先都要获得锁,即该语句要放到synchronize语句块内部。如果没有加锁会抛出异常:Exception in thread "main" java.lang.IllegalMonitorStateException

1.object.wait() 该方法会使线程放弃锁资源和cpu资源进入WAITING或者TIMED_WAITING状态。线程被加入到等待队列。

2.object.notify() 从等待队列中任意取一个线程唤醒,并将其放入同步队列中,唤醒哪个线程它使任意的。

3.object.notifyAll() 将等待队列里面的线程全部唤醒,加入到同步队列中。

三.管道输入输出流
对于Pipe类型的流,必须要先进行绑定,也就是调用connect()方法,如果没有将输入输出流进行绑定的话,对于流的访问会抛出IOException异常。
主要包括两类:
1.字节流
pipeOutputStream()
pipeInputStream()
2.字符流
pipeReader()
PipeWriter()

四.Thread.join()
用于等待其他线程执行完之后再继续工作。如果线程A执行了thread.join(),则A线程会等待thread线程终止后才继续执行后续内容。

五.ThreadLocal的使用 //主要用于数据库连接和session管理
ThreadLocal即是线程变量,是一个以ThreadLocal对象为键,任意对象位置的存储结构。
ThreadLocal类下有个ThreadLocalMap的子类,他是一个map类型结构,维护一个Entry(threadlocal,value)类型数组。 每个线程都拥有一个个ThreadLocalMap类型的变量threadLocals,它存储了多个该线程拥有的(threadlocal,value)键值对。

源码比较简单,主要看一下set()和get()方法
set()方法

    public void set(T value) {
        Thread t = Thread.currentThread();//获取当前线程
        ThreadLocalMap map = getMap(t);//获取当前线程的ThreadLocalMap
        if (map != null) {
            map.set(this, value);//设置值
        } else {
            createMap(t, value);//建一个
        }
    }
    
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

get()方法

public T get() {
        Thread t = Thread.currentThread();//获取当前线程
        ThreadLocalMap map = getMap(t);//获取当前线程的ThreadLocalMap
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);//通过本ThreadLocal获取到Entry键值对
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;//通过Entry获取值
                return result;
            }
        }
        return setInitialValue();//如果获取到的Entry为空,则需要初始化,初始化时值为null,返回的值也为null
    }
 private T setInitialValue() {
        T value = initialValue();//查看源码返回的时null
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            map.set(this, value);
        } else {
            createMap(t, value);//直接创建value为null
        }
        if (this instanceof TerminatingThreadLocal) {
            TerminatingThreadLocal.register((TerminatingThreadLocal<?>) this);
        }
        return value;
    }

觉得笔者写的不错,请多多支持,点赞收藏加关注。
人非圣贤,孰能无过,有不准确的地方请多多指正。