zoukankan      html  css  js  c++  java
  • 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注释

     输出:

    成灰之前,抓紧时间做点事!!
  • 相关阅读:
    JavaScript
    css-装饰
    html 标签
    remote connect openshift mysql
    MySQL
    how to run a continuous background task on OpenShift
    openshifit 安装 redis
    Python之路,Day6
    选择排序
    C语言实现链表
  • 原文地址:https://www.cnblogs.com/jony-it/p/10833328.html
Copyright © 2011-2022 走看看