黑马程序员 ---- 同步函数的锁

  ------- android培训java培训、期待与您交流! ----------




同步函数的锁:函数需要被对象调用,函数都有一个所属的对象引用 this ,因此同步函数的锁就是 this 。


例1:不正确的同步函数示例。 (接上面卖票的程序,上面卖票的程序问题已由同步代码块解决,这里用同步函数来解决)     【误】

class Demo implements Runnable
{	
	private int tickets = 100;
	
	public synchronized void run()        // 只有一个线程从此处进去,其他都没有进
	{
			while(true)                 // 此处不用同步
			{
				if(tickets>0)           // 只需要同步 if里面的共享数据
                {
                    try{Thread.sleep(10);}catch(Exception e){}
                    System.out.println(Thread.currentThread().getName()+"run...."+tickets--);
                }
			}
	}
}

class Test
{
	public static void main(String[] args)
	{
		Demo d = new Demo();
		
		Thread t1 = new Thread(d);
		Thread t2 = new Thread(d);
		Thread t3 = new Thread(d);
		Thread t4 = new Thread(d);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

范例分析 :  程序可以运行,但结果不正确。错误是只有一个线程在卖票,其它线程都没卖, 原因在于一个线程进入了锁内之后,在锁内执行到把票都卖完还不能出来,因为还符合 while 条件,所以线程一直在里边运行着,其它线程都进不去。


例2: 正确的同步函数实例。  【正】


class Demo implements Runnable
{	
	private int tickets = 1000;
	
	public void run()
	{
			while(true)
			{
				this.show();
			}
	}
	
	public synchronized void show()
	{
		if(tickets>0)         // 将要同步的代码块单独封装起来
		{
			try{Thread.sleep(10);}catch(Exception e){}
			System.out.println(Thread.currentThread().getName()+".......run...."+tickets--);
		}
	}
}

class Test
{
	public static void main(String[] args)
	{
		Demo d = new Demo();
		
		Thread t1 = new Thread(d);
		Thread t2 = new Thread(d);
		Thread t3 = new Thread(d);
		
		
		t1.setName("zhang");    // 设置线程的名称
		t1.start();
		t2.setName("wang");
		t2.start();
		t3.setName("lisi");
		t3.start();
	}
}

例3:验证程序示例。 使用两个线程来买票。一个线程在同步代码块中。一个线程在同步函数中。都在执行买票动作。   【正】


class Demo implements Runnable
{	
	private int tickets = 100;
	
	boolean flag = true;
	
	public void run()
	{
		if(flag)
		{
			while(true)
			{
				synchronized(this)
				{
					if(tickets>0)
					{
						try{Thread.sleep(10);}catch(Exception e){}
						System.out.println(Thread.currentThread().getName()+"...........code..........:"+tickets--);
					}
				}
			}
		}
		else
			while(true)
			{
				this.show();
			}
	}
	
	public synchronized void show()
	{
		if(tickets>0)          
		{
			try{Thread.sleep(10);}catch(Exception e){}
			System.out.println(Thread.currentThread().getName()+"++++++++show+++++++++"+tickets--);
		}
	}
}

class Test
{
	public static void main(String[] args)
	{
		Demo d = new Demo();
		
		Thread t1 = new Thread(d);
        t1.setName("zhang");
		Thread t2 = new Thread(d);
        t2.setName("wang");
		
		t1.start();
		try{Thread.sleep(10);}catch(Exception e){}
		d.flag = false;
		t2.start();
	}
}


            

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值