Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2877475
  • 博文数量: 471
  • 博客积分: 7081
  • 博客等级: 少将
  • 技术积分: 5369
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-04 21:55
文章分类

全部博文(471)

文章存档

2014年(90)

2013年(69)

2012年(312)

分类: Java

2012-07-26 10:45:58

在java中,如果某个对象是非线程安全的共享资源,在多线程环境下,如果不加任何限制,对该资源的访问会存在冲突问题(比如多线程访问打印对象的属性序列号 如下面代码:)。针对这个问题,有以下几种解决方案:

1.加synchronized关键字,这种做法会限制并发访问,影响效率;

2.使用ThreadLocal维护共享资源(变量),为每个使用共享资源(变量)的线程提供独立的变量副本,从而避免冲突问题

点击(此处)折叠或打开

  1. package test.threadlocal;
  2. /*
  3.  * 序列号产生类
  4.  */
  5. public class SequenceNumber
  6. {
  7.     //序列号变量
  8.     private int segNum=0;
  9.     //获取下一个序列值
  10.     public int getNextNum(){
  11.         return ++segNum;
  12.     }
  13. }
  14. package test.threadlocal;
  15. public class ThreadPrint extends Thread{
  16.     //序列号产生类对象
  17.     private SequenceNumber sn;
  18.     //构造函数
  19.     public ThreadPrint(String name,SequenceNumber sn) {
  20.         super(name);
  21.         this.sn = sn;
  22.     }
  23.     public void run() {
  24.         for (int i = 0; i < 3; i++) {
  25.             //每个线程打出3个序列值
  26.             System.out.println(getName()+":sn--->" + sn.getNextNum());
  27.         }
  28.     }
  29. }
  30. package test.threadlocal;
  31. public class TestThreadLocal
  32. {
  33.      public static void main(String[] args)
  34.      {
  35.      SequenceNumber sn = new SequenceNumber();
  36.      // 3个线程共享sn,各自产生序列号
  37.      ThreadPrint t1 = new ThreadPrint("A",sn);
  38.      ThreadPrint t2 = new ThreadPrint("B",sn);
  39.      ThreadPrint t3 = new ThreadPrint("C",sn);
  40.      t1.start();
  41.      t2.start();
  42.      t3.start();
  43.      }
  44. }
  45. A:sn--->1
  46. C:sn--->3
  47. B:sn--->2
  48. C:sn--->5
  49. C:sn--->7
  50. A:sn--->4
  51. A:sn--->8
  52. B:sn--->6
  53. B:sn--->9
把共享的序列号变量,用ThreadLocal变量来指定

点击(此处)折叠或打开

  1. package test.threadlocal;
  2. /*
  3.  * 序列号产生类
  4.  */
  5. public class SequenceNumber
  6. {
  7.      //序列号变量,通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值
  8.     private static ThreadLocal seqNum = new ThreadLocal() {
  9.         public Integer initialValue() {
  10.             return 0;
  11.         }
  12.     };
  13.     //获取下一个序列值
  14.     public int getNextNum() {
  15.         seqNum.set(seqNum.get() + 1);
  16.         return seqNum.get();
  17.     }
  18. }
输出:
B:sn--->1
C:sn--->1
A:sn--->1
C:sn--->2
B:sn--->2
C:sn--->3
A:sn--->2
A:sn--->3
B:sn--->3




阅读(778) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~