当前位置:首页 > 后端开发 > java多线程全局变量共享问题

java多线程全局变量共享问题

6个月前 (05-23)21

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

package ThreadTest;

public class Counter {

	private int x =0;
	
	// 计数方法
	public void count() {
		for(int i=0;i<=10;i++) {
			x = x+i;
		}
		System.out.println(Thread.currentThread().getName()+"--"+x);
	}
	
	public static void main(String[] args) {
		// 定义线程实现接口
		Runnable runnable = new Runnable(){
			Counter counter = new Counter();
			@Override
			public void run() {
				counter.count();
			}
		};
		// 启动10个线程
		for(int i=0;i<10;i++) {
			new Thread(runnable).start();
		}
	}
}

            实际输出是无规则的。

解决方案一:

package ThreadTest;

public class Counter {

	ThreadLocal<Integer> th=new ThreadLocal<Integer>(){
		protected Integer initialValue() {
			return 0;
		}
	};
	// 计数方法
	public void count() {
		for(int i=0;i<=10;i++) {
			th.set(th.get()+i);
		}
		System.out.println(Thread.currentThread().getName()+"--"+th.get());
	}
	
}

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

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

解决方案二:

将全局变量局部化

public class Count {


    public void count() {  
        int x =0;
        for(int i = 1; i <= 10; i++) {
            x=x+i;
        }  
        System.out.println(Thread.currentThread().getName() + "-" + x);  
    }  
}

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

解决方案三:对象局部化

public static void main(String[] args) {
       Runnable runnable = new Runnable() {               
           public void run() {  
            Count count = new Count();
               count.count();  
           }  
       };  
       for(int i = 0; i < 10; i++) {  
           new Thread(runnable).start();  
       }  
}

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

作者:weixin_40018934
来源链接:https://blog.csdn.net/weixin_40018934/article/details/81075141

“java多线程全局变量共享问题” 的相关文章

什么场景中会用到java多线程(转)

问:对多线程有些了解,但是不太清楚具体的应用场景,能简单说一下你遇到的多线程编程的场景吗?回答一:最典型的如:1、用户注册完成送大礼包/积分之类,且积分等也是另一个系统并比较耗时;且这类...

Java 并发性和多线程

Java 并发性和多线程

阅读目录 一、介绍 二、多线程的优点 三、多线程的代价 四、如何创建并运行 java 线程 五、竞态条件与临界区 六、线程安全与共...

Java常用集合源码级深度解析

Java常用集合源码级深度解析

  Java集合工具包位于Java.util包下,包含了很多常用的数据结构,如数组、链表、栈、队列、集合、哈希表等。学习Java集合框架下大致可以分为如下五个...

愚人节老板发话了,免费送书 + 免费入驻Java知识星球!!

愚人节老板发话了,免费送书 + 免费入驻Java知识星球!!

愚人节快乐,今天的活动很重磅! 1、免费送5本重量级技术书籍,不骗人,小程序随机抽奖送出哦! 2、免费进星球,哈哈不可能,愚人节快乐!不过今天有重大优惠,见下文! 活动一:免...

java判断不为null

java判断不为null

字符串或串(String)是由数字、字母、下划线组成的一串字符。一般记为 s=“a1a2···an”(n>=0)。它是编程语言中表示文本的数据类型。...

java中多线程的实现

1.JAVA多线程实现方式 JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结...

Java的多线程机制系列:(三)synchronized的同步原理

Java的多线程机制系列:(三)synchronized的同步原理

synchronized关键字是JDK5之实现锁(包括互斥性和可见性)的唯一途径(volatile关键字能保证可见性,但不能保证互斥性,详细参见后文关于vloatile的详述章节),其在...

JAVA多线程下高并发的处理经验

JAVA多线程下高并发的处理经验

java中的线程:java中,每个线程都有一个调用栈存放在线程栈之中,一个java应用总是从main()函数开始运行,被称为主线程。一旦创建一个新的线程,就会产生一个线程栈。...

使用JDK8的新特性-Optional来避免Java空指针异常

使用JDK8的新特性-Optional来避免Java空指针异常

什么是Optional 领域模型概念可参考:浅谈领域模型 使用Optional package com.github.ybqd...

java中List集合分批处理

java中List集合分批处理

java中List集合分批处理 在项目中存在list集合数据量过大,需要对这个list集合进行分批处理,自己写了一个list分批处理的一个算法...