ThreadLocal与synchronized多线程并发访问区别2.doc_第1页
ThreadLocal与synchronized多线程并发访问区别2.doc_第2页
ThreadLocal与synchronized多线程并发访问区别2.doc_第3页
ThreadLocal与synchronized多线程并发访问区别2.doc_第4页
ThreadLocal与synchronized多线程并发访问区别2.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

由上面可以知道,使用同步是非常复杂的。并且同步会带来性能的降低。Java提供了另外的一种方式,通过ThreadLocal可以很容易的编写多线程程序。从字面上理解,很容易会把ThreadLocal误解为一个线程的本地变量。其它ThreadLocal并不是代表当前线程,ThreadLocal其实是采用哈希表的方式来为每个线程都提供一个变量的副本。从而保证各个线程间数据安全。每个线程的数据不会被另外线程访问和破坏。 我们把第一个例子用ThreadLocal来实现,但是我们需要些许改变。 Student并不是一个私有变量了,而是需要封装在一个ThreadLocal对象中去。调用ThreadLocal的set方法,ThreadLocal会为每一个线程都保持一份Student变量的副本。所以对student的读取操作都是通过ThreadLocal来进行的。Java代码1. protected Student getStudent() 2. Student student = (Student)studentLocal.get(); 3. if(student = null) 4. student = new Student(); 5. studentLocal.set(student); 6. 7. return student; 8. 9. 10. protected void setStudent(Student student) 11. studentLocal.set(student); 12. accessStudent()方法需要做一些改变。通过调用getStudent()方法来获得当前线程的Student变量,如果当前线程不存在一个Student变量,getStudent方法会创建一个新的Student变量,并设置在当前线程中。 Student student = getStudent(); student.setAge(age); accessStudent()方法中无需要任何同步代码。 完整的代码清单如下: TreadLocalDemo.javaJava代码1. public class TreadLocalDemo implements Runnable 2. private final static ThreadLocal studentLocal = new ThreadLocal(); 3. 4. public static void main(String agrs) 5. TreadLocalDemo td = new TreadLocalDemo(); 6. Thread t1 = new Thread(td,a); 7. Thread t2 = new Thread(td,b); 8. 9. t1.start(); 10. t2.start(); 11. 12. 13. 14. 15. 16. 17. /* (non-Javadoc) 18. * see java.lang.Runnable#run() 19. */ 20. public void run() 21. accessStudent(); 22. 23. 24. publicvoid accessStudent() 25. 26. String currentThreadName = Thread.currentThread().getName(); 27. System.out.println(currentThreadName+ is running!); 28. Random random = new Random(); 29. int age = random.nextInt(100); 30. System.out.println(thread +currentThreadName + set age to:+age); 31. Student student = getStudent(); 32. student.setAge(age); 33. System.out.println(thread +currentThreadName+ first read age is:+student.getAge(); 34. try 35. Thread.sleep(5000); 36. 37. catch(InterruptedException ex) 38. ex.printStackTrace(); 39. 40. System.out.println(thread +currentThreadName + second read age is:+student.getAge(); 41. 42. 43. 44. protected Student getStudent() 45. Student student = (Student)studentLocal.get(); 46. if(student = null) 47. student = new Student(); 48. studentLocal.set(student); 49. 50. return student; 51. 52. 53. protected void setStudent(Student student) 54. studentLocal.set(student); 55. 56. 运行程序后,屏幕输出: b is running! thread b set age to:0 thread b first read age is:0 a is running! thread a set age to:17 thread a first read age is:17 thread b second read age is:0 thread a second read age is:17 可见,使用ThreadLocal后,我们不需要任何同步代码,却能够保证我们线程间数据的安全。 而且,ThreadLocal的使用也非常的简单。 我们仅仅需要使用它提供的两个方法 void set(Object obj) 设置当前线程的变量的副本的值。 Object get() 返回当前线程的变量副本 另外ThreadLocal还有一个protected的initialValue()方法。返回变量副本在当前线程的初始值。默认为null ThreadLocal是怎么做到为每个线程都维护一个变量的副本的呢? 我们可以猜测到ThreadLocal的一个简单实现Java代码1. public class ThreadLocal 2. 3. private Map values = Collections.synchronizedMap(new HashMap(); 4. public Object get() 5. 6. Thread curThread = Thread.currentThread(); 7. Object o = values.get(curThread); 8. if (o = null & !values.containsKey(curThread) 9. 10. o = initialValue(); 11. values.put(curThread, o); 12. 13. return o; 14. 15. 16. public void set(Object newValue) 17. 18. values.put(Thread.currentThread(), newValue); 19. 20. 21. public Object initialValue() 22. 23. return null; 24. 25. 由此可见,ThreadLocal通过一个Map来为每个线程都持有一个变量副本。这个map以当前线程为key。与synchronized相比,ThreadLocal是以空间换时间的策略来实现多线程程序。 Synchronized还是ThreadLocal? ThreadLocal以空间换取时间,提供了一种非常简便的多线程实现方式。因为多个线程并发访问无需进行等待,所以使用ThreadLocal会获得更大的性能。虽然使用ThreadLocal会带来更多的内存开销,但这点开销是微不足道的。因为保存在ThreadLocal中的对象,通常都是比较小的对象。另外使用ThreadLocal不能使用原子类型,只能使用Object类型。ThreadLocal的使用比synchronized要简单得多。 ThreadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别。synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论