Java线程是一项非常基本和重要的技术,在偏底层和偏技术的Java程序中不可避免地要使用到Java多线程技术,那么数据的共享也就是我们必须考虑的问题之一,自然我也就会想到ThreadLocal和synchronized。
ThreadLocal使用场合主要解决多线程中数据因并发产生不一致问题。ThreadLocal为每个线程中并发访问的数据提供一个副本,通过访问副本来运行业务,这样的结果虽然耗费一些内存,但可以大大降低线程同步所带来性能消耗,同时也减少了线程并发控制的复杂度。synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。二者虽然都是解决多线程并发访问的问题,但是区别很大。Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。下面是一个小例子,使用ThreadLocal时我们可以参照一下它的写法:
import java.util.HashMap; import java.util.Map; import java.util.Random; public class ThreadLocalTest { private static ThreadLocal<Integer> x = new ThreadLocal<Integer>(); private static ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>(); public static void main(String[] args) { for(int i=0;i<2;i++){ new Thread(new Runnable(){ @Override public void run() { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has put data :" + data); x.set(data); MyThreadScopeData.getThreadInstance().setName("name" + data); MyThreadScopeData.getThreadInstance().setAge(data); new A().get(); new B().get(); } }).start(); } } static class A{ public void get(){ int data = x.get(); System.out.println("A from " + Thread.currentThread().getName() + " get data :" + data); MyThreadScopeData myData = MyThreadScopeData.getThreadInstance(); System.out.println("A from " + Thread.currentThread().getName() + " getMyData: " + myData.getName() + "," + myData.getAge()); } } static class B{ public void get(){ int data = x.get(); System.out.println("B from " + Thread.currentThread().getName() + " get data :" + data); MyThreadScopeData myData = MyThreadScopeData.getThreadInstance(); System.out.println("B from " + Thread.currentThread().getName() + " getMyData: " + myData.getName() + "," + myData.getAge()); } } } class MyThreadScopeData{ private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>(); private String name; private int age; private MyThreadScopeData(){} public static /*synchronized*/ MyThreadScopeData getThreadInstance(){ MyThreadScopeData instance = map.get(); if(instance == null){ instance = new MyThreadScopeData(); map.set(instance); } return instance; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
总结:synchronized是利用锁的机制使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal却为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized正好相反,它用于在多个线程间通信时能够获得数据共享。具体使用什么我们要看编程时的应用环境而定。
时间: 2024-11-05 02:57:46