关于Java两种同步方法的理解(代码块级同步对象设置)

package xianchengThread;

class Zhangsan {
	public void say() {
		System.out.println("你给我画,我就给你书");
	}

	public void get() {
		System.out.println("张三得到了画");
	}
}

class Lisi {
	public void say() {
		System.out.println("你给我书,我就给你画");
	}

	public void get() {
		System.out.println("李四得到了书");
	}
}

public class Sisuo implements Runnable {
	private static Zhangsan zs = new Zhangsan();
	private static Lisi ls = new Lisi();
	public boolean flag = false;

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public void run() {
		if (flag) {
			synchronized (zs) {
				System.out.println("线程" + Thread.currentThread().getName()
						+ "获得了zs对象的锁");
				zs.say();
				try {
					Thread.sleep(300);
				} catch (Exception e) {
					e.printStackTrace();
				}
				synchronized (ls) {
					System.out.println("线程" + Thread.currentThread().getName()
							+ "获得了ls对象的锁");
					zs.get();
				}
			}
		} else {
			synchronized (ls) {
				System.out.println("线程" + Thread.currentThread().getName()
						+ "获得了ls对象的锁");
				ls.say();
				try {
					Thread.sleep(300);
				} catch (Exception e) {
					e.printStackTrace();
				}
				synchronized (zs) {
					System.out.println("线程" + Thread.currentThread().getName()
							+ "获得了zs对象的锁");
					ls.get();
				}
			}
		}
	}

	public static void main(String[] args) {
		Sisuo s1 = new Sisuo();
		Sisuo s2 = new Sisuo();
		s1.setFlag(true);
		s2.setFlag(false);
		Thread t1 = new Thread(s1);
		Thread t2 = new Thread(s2);
		t1.start();
		t2.start();
	}
}


 

运行结果如下(其中一种):

线程Thread-0获得了zs对象的锁
你给我画,我就给你书
线程Thread-1获得了ls对象的锁
你给我书,我就给你画
 

后经过搜索得知代码块级同步与方法级同步区别如下:

方法级同步:
- 实现方法:在要标志为同步的方法前加上synchronized关键字
- 实现原理:当调用对象的同步方法时,线程取得对象锁或监视器;如果另一个线程试图执行任何同步方法时,他就会发现他被锁住了,进入挂起状态,直到对象监视器上的锁被释放时为止。当锁住方法的线程从方法中返回时,只有一个排队等候的线程可以访问对象。

代码块级同步:
- 临界区:需要进行互斥的代码段,而非整个方法。
- 实现方法:用synchronized来指定某个对象,此对象的锁被用来对花括号内的代码进行同步控制。
- 实现原理:在进入同步代码前,必须得到object对象的锁,如果其他线程已经得到这个锁,那么就得等到锁被释放后才能进入临界区。
- 锁的作用域:只在代码块运行的时间内。

同时综合上述代码运行结果的可知,由于同步代码块中sleep方法的操作,使得线程t1获得zs对象的锁后睡眠,这时另一线程t2执行获得ls对象的锁然后睡眠。此后两线程无论哪个线程先醒来都需要获取另一个线程所持有的对象的锁才能继续执行,从而使得程序执行陷入死锁状态,此时Eclips控制台会有终端结束灯一直持红色状态,即程序未执行完。

在对其中一同步代码块中sleep方法注释掉后,程序执行出现在未注释前从未出现的一种结果,从而进一步证明了,代码块级同步对象的设置作用。

结果如下:

线程Thread-0获得了zs对象的锁
你给我画,我就给你书
线程Thread-0获得了ls对象的锁
张三得到了画
线程Thread-1获得了ls对象的锁
你给我书,我就给你画
线程Thread-1获得了zs对象的锁
李四得到了书

 

——————————————————————————————————————————————

本文出自 “Mr果冻de空间” 博客,请务必保留此出处http://mrguodong.blog.51cto.com/2911964/862109

————————————————————————————————————————————————————

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值