JAVA 多线程(7):join 与threadLocal
join:
说明:线程A等待线程B 的结果或者等待线程B执行结束
private static String test = "begin"; public static void main(String[] args){ Thread t = new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); test = "change"; } },"线程A"); System.out.println(test); t.start(); try { t.join(); System.out.println(test); } catch (InterruptedException e) { e.printStackTrace(); } }
输出:
由结果看出,主线程等待子线程结束后再继续执行。
join与synchronized 的不同在于:虽然都会阻塞,但是join内部使用的是wait 进行等待,而synchronized 使用的时候对象监视器。
join(long)
说明:等待子线程指定时间后继续执行当前线程
对上面的代码进行更改:
输出:
由结果看出,主线程等待2秒,在子线程未执行完时不再等待。
join(long) 与 sleep(long)的区别在于:join是wait 在子线程执行完毕后会释放锁,但是sleep 不会。
注意的是由于join内部是wait实现,所以如果多个线程都在抢都一把锁,有可能会导致join后面的方法先执行。
线程拥有各自线程的共享变量:
ThreadLocal:每个线程绑定自己的值,存储各自线程的私有数据。
private static ThreadLocal<String> threadLocal = new ThreadLocal<String>(); private static void setV(String v){ threadLocal.set(v); } public static void main(String[] args){ Thread t= new Thread(new Runnable() { @Override public void run() { setV("线程A的数据"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + threadLocal.get()); } },"线程A"); Thread t2= new Thread(new Runnable() { @Override public void run() { setV("线程B的数据"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + threadLocal.get()); } },"线程B"); t.start(); t2.start(); // 主线程set setV("主线程数据"); System.out.println(Thread.currentThread().getName() + threadLocal.get()); }
输出:
由结果看出 各自线程从threadLocal 取出的数据都是各自线程的数据,互不干涉。
设置threadLocal初始化值:重写threadlocal initialValue()方法,返回初始化值
public class ThreadLocalExt extends ThreadLocal{ @Override protected Object initialValue() { return "我是初始化"; } }
把上面例子的start 和主线set注释
输出:
成灰之前,抓紧时间做点事!!