ThreadLocal介绍及使用

ThreadLocal使用场合:主要是解决多线程中类变量、成员变量在并发访问中产生不一致的问题。ThreadLocal特点:为每个线程中使用的类变量、成员变量创建一个类变量、成员变量的副本,每个线程在运行中都是访问自己内部的副本变量。

ThreadLocal缺点:由于每个线程都创建了一个副本,因此消耗的内存资源会比没有使用ThreadLocal要多。

案例一:多线程环境下,成员变量的变化 

public class ThreadB implements Runnable{
    private Integer count;
    private ThreadTest threadTest;
    
    public ThreadTest getThreadTest() {
        return threadTest;
    }

    public void setThreadTest(ThreadTest threadTest) {
        this.threadTest = threadTest;
    }

    @Override
    public void run() {
        Integer count = threadTest.getCount();
        while(count>=0) {
            Integer c = count--;
            threadTest.setCount(c);
            System.out.println(Thread.currentThread().getName()+"======"+c);
        }
    }
}
public class ThreadTest {
    private Integer count = 10;//成员变量
    @Test
    public void test() throws InterruptedException {
        ThreadTest threadTest = new ThreadTest();
        ThreadB threadB = new ThreadB();
        threadB.setThreadTest(threadTest);
        Thread t1 = new Thread(threadB);
        t1.start();
        t1.join();//join()方法的作用是t1线程执行完以后,才会执行后面的代码
        Integer c = threadTest.getCount();
        while (c >0) {
            System.out.println(Thread.currentThread().getName()+":"+c--);
        }

    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }
}

执行结果:

Thread-0======10
Thread-0======9
Thread-0======8
Thread-0======7
Thread-0======6
Thread-0======5
Thread-0======4
Thread-0======3
Thread-0======2
Thread-0======1
Thread-0======0

由此发现 main主线程已经没有任何数据可以打印了,因为count变量已经变为0了,成员变量发生了改变。

案例二:使用ThreadLocal 

public class ThreadA implements Runnable{
    private ThreadLocalTest threadLocalTest;


    public ThreadLocalTest getThreadLocalTest() {
        return threadLocalTest;
    }

    public void setThreadLocalTest(ThreadLocalTest threadLocalTest) {
        this.threadLocalTest = threadLocalTest;
    }

    @Override
    public void run() {
        Integer count = threadLocalTest.getThreadLocal().get();
        while(count>=0) {
            Integer c = count--;
            threadLocalTest.getThreadLocal().set(c);
            System.out.println(Thread.currentThread().getName()+"======"+ threadLocalTest.getThreadLocal().get());
        }
    }
}
public class ThreadLocalTest {
    private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(){
        protected Integer initialValue() {
            return 10;
        }
    };//成员变量
    @Test
    public void test() throws InterruptedException {
        ThreadLocalTest threadLocalTest = new ThreadLocalTest();
        ThreadA threadA = new ThreadA();
        threadA.setThreadLocalTest(threadLocalTest);
        Thread t1 = new Thread(threadA);
        t1.start();
        t1.join();//t1线程执行完以后,才会执行后面的代码
        Integer c = threadLocalTest.getThreadLocal().get();
        while (c >=0) {
            System.out.println(Thread.currentThread().getName()+":"+c--);
        }

    }


    public ThreadLocal<Integer> getThreadLocal() {
        return threadLocal;
    }

    public void setThreadLocal(ThreadLocal<Integer> threadLocal) {
        this.threadLocal = threadLocal;
    }
}

执行结果:

Thread-0======10
Thread-0======9
Thread-0======8
Thread-0======7
Thread-0======6
Thread-0======5
Thread-0======4
Thread-0======3
Thread-0======2
Thread-0======1
Thread-0======0
main:10
main:9
main:8
main:7
main:6
main:5
main:4
main:3
main:2
main:1
main:0

Thread-0线程执行有数据打印,main主线程执行也有数据打印,互不影响,因为两个线程都是用自己内部的变量副本。

 

转载于:https://my.oschina.net/xzjl/blog/1507240

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值