线程安全之Runnable多实例和单实例

多个线程访问共享变量,会导致线程安全问题,导致共享变量值被非预期改变。

那么什么情况会导致共享变量存在呢?

1、类的静态变量

2、多个线程,单个Runable实例,其内部全局变量是共享的

本文主要说明Runnable多实例和单实例(即:上述第2点)的区别及可能产生的问题,详细见代码及注释。

import java.util.concurrent.TimeUnit;

/**
 *
 */
public class GlobalVariableTest {

	public GlobalVariableTest() {

	}

	class Task implements Runnable {

		private int idx;

		private String taskId;

		public Task(String taskId) {
			this.taskId = taskId;
		}

		public void run() {
			while (true) {
				try {
					TimeUnit.MILLISECONDS.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() +"     "+ (++idx) + this.taskId);
			}
		}
	}

	public void test() {
		// 多个线程,多个Runnable实例,各自独立,没有线程安全问题(除了内部静态变量访问)
//		new Thread(new Task("task1")).start();
//		new Thread(new Task("task2")).start();
//		new Thread(new Task("task3")).start();
//		new Thread(new Task("task4")).start();

		// 多个线程,单个Runnable实例,变量共享,存在线程安全问题
		Task task = new Task("task");
		new Thread(task).start();
		new Thread(task).start();
		new Thread(task).start();
		new Thread(task).start();

	}

	public static void main(String[] args) {
		new GlobalVariableTest().test();
	}
}

最后说明,避免线程安全问题的方法:

1、使用多实例多线程;

2、对于共享变量的操作加锁;

3、使用ThreadLocal存放线程变量,代替Runnable全局共享变量;

猜你喜欢

转载自blog.csdn.net/tobearc/article/details/88412603