java高并发全局变量共享问题(解决多个用户同时访问造成数据错乱)

         先看下面问题:多个线程访问全局变量x,然后将x与i累加,启动10个线程,想让每个线程的输出结果都是一样的55,但是实际不是的。

注意:多个接口共享则全局变量为空
  1. package ThreadTest;
  2. public class Counter {
  3. private int x = 0;
  4. // 计数方法
  5. public void count() {
  6. for( int i= 0;i<= 10;i++) {
  7. x = x+i;
  8. }
  9. System.out.println(Thread.currentThread().getName()+ "--"+x);
  10. }
  11. public static void main(String[] args) {
  12. // 定义线程实现接口
  13. Runnable runnable = new Runnable(){
  14. Counter counter = new Counter();
  15. @Override
  16. public void run() {
  17. counter.count();
  18. }
  19. };
  20. // 启动10个线程
  21. for( int i= 0;i< 10;i++) {
  22. new Thread(runnable).start();
  23. }
  24. }
  25. }

            实际输出是无规则的。

解决方案一:


   
   
   
   
  1. package ThreadTest;
  2. public class Counter {
  3. ThreadLocal th= new ThreadLocal(){
  4. protected Integer initialValue() {
  5. return 0;
  6. }
  7. };
  8. // 计数方法
  9. public void count() {
  10. for( int i= 0;i<= 10;i++) {
  11. th.set(th.get()+i);
  12. }
  13. System.out.println(Thread.currentThread().getName()+ "--"+th.get());
  14. }
  15. }

用ThreadLocal,输出结果是55,ok!

由此可以证明,ThreadLocal为每一个线程保存每一个变量,而且每个线程拿到的都是自己的那一份。

解决方案二:

将全局变量局部化


   
   
   
   
  1. public class Count {
  2. public void count() {
  3. int x = 0;
  4. for( int i = 1; i <= 10; i++) {
  5. x=x+i;
  6. }
  7. System.out.println(Thread.currentThread().getName() + "-" + x);
  8. }
  9. }

每个线程都有一份自己的局部变量,因此不会产生线程问题。

解决方案三:对象局部化


   
   
   
   
  1. public static void main(String[] args) {
  2. Runnable runnable = new Runnable() {
  3. public void run() {
  4. Count count = new Count();
  5. count.count();
  6. }
  7. };
  8. for( int i = 0; i < 10; i++) {
  9. new Thread(runnable).start();
  10. }
  11. }

每个对象都会有一个自己的全局变量。不会产生线程问题。

你可能感兴趣的:(Java初级)