线程安全Synchronized,lock.volatile

synchronized 控制访问

springboot现在都是原子事务控制访问

对资源加上控制对象,在一个线程访问时,其他线程只能等待。因为那个锁对象只能由一个占用,第二个线程来时找不到。
1: 可创建任意对象
2:多个线程使用统一锁对象

第一种直接synchronized

public class runable implments Runable{
private int ticket=20;   //定义20个票
Object obj =new Object();  //创建锁对象
			@override
			public void run(){    //实现卖票逻辑
				while(true){
				Synchronized(obj) {       //!!!同步实现,传入锁对象,并将访问公用对象的代码放入其中
					if(ticket>0){   //先判断有无票
							try{ Thread.sleep(1000);  //睡1s等程序跑一会
							}catch(in e){  sys(e);
							 }
							 ticket--;    //票数减一
					}
					
					}
				}
			
			}

}


//第二种使用synchronized 修饰的方法,可以实现多个线程的调用。在run(){}中调用check()
public synchronized void check(){
	if(ticket>0){   //先判断有无票
							try{ Thread.sleep(1000);  //睡1s等程序跑一会
							}catch(in e){  sys(e);
							 }
							 ticket--;    //票数减一
					}
}

main{          //通过实现Runable接口,创建多线程
Runable ru=new Runable();
Thread t1=new Thread(ru);
Thread t2=new Thread(ru);
Thread t3=new Thread(ru);
t1.start();
t2.start();
t3.start();
}

加锁之后的程序,如果出现异常那么锁会被释放,其他线程就能执行了。
锁又分为偏向锁(假装加锁,其实没有,因为就这一个线程),自旋锁(一个线程占用,其他线程在资源周围打转,试探,最多循环10次,还没有获得锁的话就会变成重量级锁),重量级锁(os去进入等待队列,申请资源)
volatile
线程可见,在一个线程中修改完之后,能反馈到其他线程中。

class T{
bool flag =true;
	public void test(){
		while(true){
		sout("flag为true")
		}
	}
}
main函数
T t= new T();
new Thread(t::test ,"t1线程").start();
		try{
		t.sleep(1000);
		}catch(InteruptException e){
		e.printStackTrace()
		}
t.flag=false;
 //此时,设置flag的值t线程不会停止。需要在flag前加上volatile使其所有人可见才行。
 

java提供的automic包有intteger
CAS(乐观锁)操作:cas(地址,期的望值,要改为什么),cas(地址,10,12)我要看到它是10,才进去将它改为12,如果有人先行一步,我就不进去。会产生ABA问题(线程1取钱,线程2取钱,线程3存钱,1先运行,二卡住了,三紧随1运行,原来100,1取了50,3加了50,此时钱成100了,可是2旧期望值是100,本该紧随1执行,然后执行失败,可是3先执行了,导致2执行通过,造成失误),防止这个问题加上版本号。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值