ThreadLocal和Synchronized区别
前言
最近项目中使用到了ThreadLocal变量,所以学习了一下ThreadLocal以及与Synchronized的区别,并记录下来。
正文
1、ThreadLocal变量的理解:
使用ThreadLocal变量,当多个线程访问该变量时,都会为每个线程提供一个独立的变量副本,并且线程对该变量的操作实质是对自己变量副本的操作,不会对其它线程有影响。
2、ThreadLocal和Synchronized的区别:
(1)相同点:ThreadLocal和Synchronized都是为了解决多线程中访问相同变量的冲突问题。
(2)不同点:
①、ThreadLocal:以空间换时间,为每个线程提供一个变量副本,消耗较多的内存,但是多个线程可以同时访问该变量而且相互不会影响。
②、Synchronized:以时间换空间,多个线程访问的是同一个变量,但是当多个线程同时访问该变量时,需要抢占锁,并且等待获取锁的线程释放锁,会消耗较多的时间。
3、通过代码区别ThreadLocal和Synchronized:
(1)普通的代码:
public class NormalTest implements Runnable{ private Integer num = 0; private Integer addAndGetNum(){ ++num; return num; } @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + "----" + addAndGetNum()); } } public static void main(String[] args) { NormalTest normalTest = new NormalTest(); new Thread(normalTest).start(); new Thread(normalTest).start(); new Thread(normalTest).start(); // 运行结果 // Thread-1----2 // Thread-1----3 // Thread-0----1 // Thread-2----1 // Thread-0----4 // Thread-2----5 // Thread-2----7 // Thread-0----6 } }
(2)使用Synchronized代码:
public class SynchronizeTest implements Runnable{ private Integer num = 0; private synchronized Integer addAndGetNum(){ ++num; return num; } @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + "----" + addAndGetNum()); } } public static void main(String[] args) { SynchronizeTest synchronizeTest = new SynchronizeTest(); new Thread(synchronizeTest).start(); new Thread(synchronizeTest).start(); new Thread(synchronizeTest).start(); // 运行结果 // Thread-1----2 // Thread-2----3 // Thread-0----1 // Thread-0----6 // Thread-2----5 // Thread-1----4 // Thread-2----8 // Thread-0----7 // Thread-1----9 } }
(3)使用ThreadLocal代码:
public class ThreadLocalTest implements Runnable{ private ThreadLocal<Integer> num = ThreadLocal.withInitial(()->0); private Integer addAndGetNum(){ num.set(num.get() + 1); return num.get(); } @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + "----" + addAndGetNum()); } } public static void main(String[] args) { ThreadLocalTest threadLocalTest = new ThreadLocalTest(); new Thread(threadLocalTest).start(); new Thread(threadLocalTest).start(); new Thread(threadLocalTest).start(); // 运行结果 // Thread-0----1 // Thread-0----2 // Thread-0----3 // Thread-1----1 // Thread-2----1 // Thread-1----2 // Thread-2----2 // Thread-2----3 // Thread-1----3 } }

浙公网安备 33010602011771号