欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java并发编程线程安全问题

程序员文章站 2022-04-23 14:17:01
...

1.线程安全:管理对共享的可变状态的访问。状态----指的是静态变量或实例变量。

2.共享:静态变量----类的使用者共享,实例变量----对象使用者共享。--目的:线程间相互交流

3.可变:对变量有写的过程,只读当然就是不可变的。

4.原子操作:意为"不可被中断的一个或一系列操作"

5.解决线程安全的思路:(对应一场安全的考试的情景)

    (1)共享变量只读;----不可变性
        情景示例:放英语听力
        代码示例:单例(饿汉式)

package chapter1.singelton01;
public class MyObject {
	//共享的静态变量,只有这里初始化,其他任何地方都不能写入
	private static MyObject myObject = new MyObject();
	
	private MyObject() {
	}
	
	public static MyObject getInstance(){
		return myObject;
	}
}
public class MyThread extends Thread {
	@Override
	public void run() {
		System.out.println(MyObject.getInstance().hashCode());
	}
}
public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}
三个线程访问的结果相同

       使用场景示例:dao层写的sql语句---private static final String SQL_INSERT = ""
                               用spring容器管理的单例bean,多数情况我们保证bean对象的不可变性

 

(2)可变变量不共享:----线程封闭

        情景示例:每个考生一份试卷
        代码示例:

package chapter1.t0020;
public class MyThread extends Thread {
	private int count = 5;
	public MyThread(String name) {
		super();
		this.setName(name);
	}
	@Override
	public void run() {
		super.run();
		while(count>0){
			count--;
			System.out.println("由"+MyThread.currentThread().getName()+"计算,count="+count);
		}
	}
}

public class Run {
	public static void main(String[] args) {
		MyThread myThread1  = new MyThread("A");
		MyThread myThread2  = new MyThread("B");
		MyThread myThread3 = new MyThread("C");
		myThread1.start();
		myThread2.start();
		myThread3.start();	
	}
}
myThread1 、myThread2、 myThread3每个对象都有自己的 count 变量 

       使用场景示例:struts2的action的原型模式,每个线程有自己的action对象
        ThreadLocal变量的设计

 

(3)共享可变的变量原子操作:----加锁

        情景示例:阅卷老师改完一题,交给下一位老师改下一题
        代码示例:单例(懒汉式)

public class MyObject {
	private static MyObject myObject;	
	private MyObject() {
	}	
	public synchronized static MyObject getInstance(){
		if(myObject!=null){
			
		}else{
			myObject = new MyObject();
		}
		return myObject;
	}
}

public class MyThread extends Thread {
	@Override
	public void run() {
		System.out.println(MyObject.getInstance().hashCode());
	}
}

public class Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

   使用场景示例:spring对bean的初始化,ConcurrentMap实现

 

锁带来的问题,以及解决这些问题锁产生的新的方案----很多技术都是对另一种技术的补充,没有替代关系,只有在特定的时间,特定的场合更适合。你的工作是找到更适合的方案,并使用它。