Java线程安全——同步锁的使用(同步代码块与同步函数的使用)

当不使用代码锁的时候是不能够保证线程的安全性问题的,不使用安全锁的时候有时候可能会出现很多问题,例如常见的问题有:
次序的扰乱:
我们经常会看到卖票等程序买的票数的张数不是紧挨着卖的,而是多个线程可能买的票的序号相同,而且可能循环已经截止了但还是会输出多余的语句,这是因为循环结束前线程已经抢夺到了cup的执行权但是没有执行出来,所以当循环结束后仍会继续打印出来多余的语句。有时候还会出现卖的票是负值的情况,这都是由于没有使用同步锁的原因

注意:
1、至少有两个线程或以上而且共享同一个资源而且操作资源的语句至少有两条 才会有线程安全问题的出现(使用同步锁)
2、有多个同步锁的时候,参数可以是随便一个对象,但是必须是同一个对象同一个锁(就是多个同步锁中的参数是一个对象才行)🔒
3、对于持有锁 ,线程睡觉不会释放锁(下面代码块中的注释中有标注持有锁)

说明:
1、对于同步锁,当一个线程进入同步锁内后,其他的线程就不能再次进入同步锁中,只有等该线程执行完同步锁中的代码之后,才会有下一个线程进入同步锁
2、对于刚从同步锁中出来的线程,仍会进入新一轮进入同步锁的线程抢夺当中


同步锁——同步代码块:


package thread;

//至少有两个线程或以上而且共享同一个资源而且操作资源的语句至少有两条   才会有线程安全(使用同步锁)
//不要同时执行run()方法

public class _a2_线程安全 {
		public static void main(String[] args) {
			MyRun2 mr = new MyRun2();
			//创建线程对象(每一个线程共用同一个对象)
			Thread t1 = new Thread(mr,"1号窗口");
			Thread t2 = new Thread(mr,"2号窗口");
			Thread t3 = new Thread(mr,"3号窗口");
			Thread t4 = new Thread(mr,"4号窗口");
			//启动
			t1.start();
			t2.start();
			t3.start();
			t4.start();
		}
}
class MyRun2 implements Runnable{
	
	private  int ticket = 100;
//	Object obj = new Object();
	@Override
	public void run() {
		// TODO Auto-generated method stub
			while(true) {
															//-----------------------同步代码块
				//this有1和0两个值
				synchronized (/*obj*/this) {//同步锁(参数需要是随便一个对象,但是必须是同一个对象同一个锁🔒)
					
				if(ticket>0) {
					try {
						Thread.sleep(10);//持有锁       线程睡觉不会释放锁
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				System.out.println(Thread.currentThread().getName()+"售出"+ticket +"号票🎫");
				ticket--;
				}else
					break;
			}
		}
	}	
}


同步锁——同步函数/同步方法:


package thread;

//至少有两个线程以上而且共享同一个资源   才会有线程安全(使用同步锁)
//不要同时执行run()方法

public class _a3_线程安全2 {
		public static void main(String[] args) {
			MyRun3 mr = new MyRun3();
			//创建线程对象(每一个线程共用同一个对象)
			Thread t1 = new Thread(mr,"1号窗口");
			Thread t2 = new Thread(mr,"2号窗口");
			Thread t3 = new Thread(mr,"3号窗口");
			Thread t4 = new Thread(mr,"4号窗口");
			//启动
			t1.start();
			t2.start();
			t3.start();
			t4.start();
		}
}
class MyRun3 implements Runnable{
	
	private  int ticket = 100;
//	Object obj = new Object();
	@Override
	public void run() {
		// TODO Auto-generated method stub
			while(true) {
				saleTicket();
				if(ticket<=0)
					break;
			}
		}
																//----------------------同步函数/同步方法
			public synchronized void saleTicket() {//这个锁是当前类的对象
				if(ticket>0) {
					try {
						Thread.sleep(10);//持有锁       线程睡觉不会释放锁
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				System.out.println(Thread.currentThread().getName()+"售出"+ticket +"号票🎫");
				ticket--;
		}		
	}	
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱睡觉的小馨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值