Java笔记十二 验证同步函数的锁

编辑器:Notepad++;学习视频:毕向东Java基础教程

(1)多线程的安全隐患(判断原则)

  • 多个线程在操作共享的数据
  • 操作共享数据的代码有多条

(2)当一个线程在执行操作共享数据的多条代码过程中,其他线程参与运算,就会导致线程安全问题的产生。

  • 解决思路:将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程不可以参与运算,必须要当前线程把这些代码执行完毕后,其他线程才可以参与运算
  • 在Java中用同步代码块解决这个问题格式:synchronized(对象){ 需要同步的代码块 }

(3)同步的好处与弊端:

  • 好处:解决了线程安全问题
  • 弊端:降低了效率,因为同步外的线程都要判断同步锁

(4)同步的前提

  • 必须保证有多个线程并使用同一个锁

(5)同步函数使用的锁是this

(6)同步函数和同步代码块的区别

  • 同步函数使用的锁是this
  • 同步代码块的锁是任意对象,建议使用同步代码块

代码示例:



/*
验证同步函数的锁
同步函数的锁与同步代码块的锁是不同的
*/

 
 //第一步:实现Runnable接口
 class Ticket implements Runnable  //不使用继承,避免多个线程卖相同的票(可将num定义成静态的来解决)
{
	private int num = 100;  //卖100张票
	boolean flag = true;
	//Object obj = new Object();
	
	//第二步:覆盖run方法
	public void run()
   {
	   if(flag)
	   {
		   while(true)
		   {
			    //synchronized(obj)
				synchronized(this)  
				{
					if(num>0)
					{
						try{Thread.sleep(14);}catch(InterruptedException e){} 
						System.out.println(Thread.currentThread().getName()+"...synCodeBlock...sale-"+num--);
					}
				
				}
			}
	   }
	   else
	   {
		   while(true)
		   {
			   this.show();  //同步函数的锁,this
		   }
	   }
   }
   
   public synchronized void show()
   {
	   if(num>0)
	   {
			try{Thread.sleep(14);}catch(InterruptedException e){}  //产生线程安全问题
			System.out.println(Thread.currentThread().getName()+"...synFunc...sale-"+num--);
	   }
   }
}

class SynFunClock
{
	public static void main(String[] args)	
    {
		//第三步:实例化Runnable接口子类对象,并作为参数传递给Thread
		Ticket t = new Ticket();  //只需要实例化一次ticket类,如果继承,需要几个线程,就得实例化几次,导致一张票卖多次的问题
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		
		//第四步:调用start()方法,开启线程
		t1.start();
		try{Thread.sleep(14);}catch(InterruptedException e){}
		t.flag = false;		
		t2.start();
		
    } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值