Java多线程基础之数据共享引发的“非线程安全”

实例变量与线程安全

     自定义线程类中的实例变量针对其他线程可以有共享与不共享之分,这在多个线程之间进行交互时是很重要的一个技术点。

    一 、不共享数据的情况

       

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("由 " + this.currentThread().getName() + " 计算,count=" + count);
			
		}
	
	}

}
public class Run {
	
	public static void main(String[] args) {

			
			
			MyThread a = new MyThread("A");
			MyThread b = new MyThread("B");
			MyThread c = new MyThread("C");
			a.start();
			b.start();
			c.start();

	}
}

以上可以看出,一共创建3个线程,每个线程都有各自的count变量,自己减少自己的count变量的值,也就是变量不共享的情况

 

  二 、不共享数据的情况

public class MyThread extends Thread {
	
	private int count = 5 ;
	
	@Override
	public void run() {
		super.run();
			count--;
			System.out.println("由 " + this.currentThread().getName() + " 计算,count=" + count);
	}
}
public class Run {
	
	public static void main(String[] args) {

			
			
			MyThread myThread = new MyThread();
			Thread a = new Thread(myThread,"A");
			Thread b = new Thread(myThread,"B");
			Thread c= new Thread(myThread,"C");
			Thread d = new Thread(myThread,"D");
			Thread e = new Thread(myThread,"E");
			a.start();
			b.start();
			c.start();
			d.start();
			e.start();

	}
}

 

 发现3有两个线程同时打印,我们想要看的结果没有重复的,而是依次递减的,从而发生了非线程安全的问题。

其实在JVM中,i -- 的操作是分为3步的

  1. 取得原有的i 值;
  2. 计算i-1;
  3. 对i 进行赋值

如果有多个线程同时访问自然出现非线程安全问题。在上面的MyThread类 的run方法中加个关键字synchronized。再试试

 

public class MyThread extends Thread {
	
	private int count = 5 ;
	
	@Override
	synchronized  public void run() {
		super.run();
			count--;
			System.out.println("由 " + this.currentThread().getName() + " 计算,count=" + count);
	}
}

线程已经安全了。

 

synchronized可以在任意对象及方法上加锁,而加锁的这段代码称为“互斥区”或者“临界区”。加上它的作用其实就是给方法上了锁,当一个线程执行这个方法时,其实就是得到了这把锁,其他线程就不会进来,等拿到锁的这个线程执行完了,其他线程才会抢这把锁,当然也包括前面那个已经运行完的线程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值