threadLocal, 是线程内通信利器 新建一个threadLocal对象后, 当使用set的时候, 对象会以自身为key, 将set的值存入当前线程对象内的一个map中.
当在线程内想要使用该threadLocal set的值的时候, 直接get就可以拿到, 在jdk 1.5后, 通过threadLocal存放在线程中的 值, 会随着线程的销毁而慢慢被jvm回收掉.
但需要注意的是在springmvc这种框架中, 针对api请求使用了线程池技术, 在单个请求结束后, 线程本身不一定会销毁, 会在新的请求过来的时候重新启用, 针对这种情况, 如果针对每次请求共享数据, 必须在请求结束后remove掉通过 threadlocal set的值
demo, 带编写
疑惑, springmvc的请求线程回收时机, 待处理
跨线程通信 在java 单进程中
使用 wait notity notifyAll()
wait 和 notify 必须在 synchronized 代码块中, 且synchronized对象必须为同一个
不建议直接使用wait 和 notify , 建议使用java.util.concurrent包中的并发组件
实例demo, 待优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 package com.luozi.thread; /** * Created by luoziyihao on 6/20/17. */ public class CrossThreadCommunicationByWaitAndNotify { public void start() { Object lock = new Object(); boolean[] locked_1 = {false}; Runnable consumerRunner1 = getRunnable1(lock, locked_1); final boolean[] locked_2 = new boolean[1]; Runnable consumerRunner2 = getRunnable2(lock, locked_2); Thread thread1 = new Thread(consumerRunner1); Thread thread2 = new Thread(consumerRunner2); thread1.start(); thread2.start(); sleepForStart(); doNotify(lock, locked_1[0] && locked_2[0]); } private void doNotify(Object lock, boolean b) { synchronized (lock) { while (b) { System.out.println("i am notify now"); lock.notifyAll(); break; } } } private void sleepForStart() { try { Thread.sleep(100L); } catch (InterruptedException e) { e.printStackTrace(); } } private Runnable getRunnable2(final Object lock, final boolean[] locked_2) { return new Runnable() { @Override public void run() { System.out.println("i am start for wait 2"); doWait(lock, locked_2); System.out.println("i am wait ok , 2"); } }; } private Runnable getRunnable1(final Object lock, final boolean[] locked_1) { return new Runnable() { @Override public void run() { System.out.println("i am start for wait 1"); doWait(lock, locked_1); System.out.println("i am wait ok, 1"); } }; } private void doWait(Object lock, boolean[] locked_1) { synchronized (lock) { try { locked_1[0] = true; lock.wait(); } catch (InterruptedException e) { throw new IllegalStateException(e); } } } public static void main(String[] args) { new CrossThreadCommunicationByWaitAndNotify().start(); } }
使用 condition, 类似的wait, notify, notifyall的效果
如果在代码中不使用 synchronized关键字, 而使用 Lock, 一般是 ReenTrantLock来做同步控制, 可以使用 lock.newCondition 来达到类似的wait, notify, notifyall的效果
对应的方法变成了 await(), signal(), signalAll()
使用管道流 pipedInputStream pipedOutputStream po.close(pi)
线程A 通过 输入流输入数据, 线程B 通过输出流读取数据
并发队列 ConcurrentLinkedQuene 非阻塞 ArrayBlockingQuene LinkedBlockingQuene 阻塞 set满了 或者 poll空了会阻塞住 ArrayBlockingQuene LinkedBlockingQuene 的区别 循环顺序表 和双向链表