Java华丽转身 —— 多线程(二)——同步

          多线程在同时运行的时候,执行的先后次序是无法确定的,如果这些线程同时操作某个公共的资源,最终的执行结果是不可预测的,所以要在代码中采取某些方法来保护公共资源,保证同一时刻只允许一个线程访问这些资源。

 


线程同步机制:

      

          1、多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问。


          2、对象的互斥锁,能保证共享数据操作的完整性。每个对象都对应于一个可称为“互斥锁”的标记,这个标记保证在任一时刻,只能有一个线程访问该对象。

 

    3Java中的线程同步是通过获取对象monitor来完成的,每个对象实例都有一个monitor。我们可以把这个monitor看成一把锁,线程在执行同步操作之前首先会针对对象实例执行锁定操作,也就是访问某个对象的synchronized方法,此时其他线程都无法再访问该synchronized方法了。

 

          4、同步代码执行完毕,则将monitor释放,此时若有其他线程要执行同样的操作,在获取对象monitor的时候也会阻塞等待,直到前面的线程将monitor释放位置。JVM保证同一时刻只有一个线程可以获得某个对象monitor


 

举例:

	public class Test implements Runnable{
	     public synchronized void run(){
		     for(int i = 0;i < 10; i++){
			     System.out.print(" " + i);
			 }
		 }
		
		 public static void main(String[] args){
		     Test t = new Test();
			 Thread t1 = new Thread(t);
			 Thread t2 = new Thread(t);
			 t1.start();
			 t2.start();
		 }
	}

如果不加锁,实现效果如下:   


加锁,实现效果如下:而且不论运行多少次,运行结果都是0-9。



同步还有以下几种实现方法:


Wait():使一个线程处于等待状态,并且释放所持有的对象的锁。

Sleep():使一个正在运行的线程处于睡眠状态,使一个静态方法,调用此方法要捕捉InterruptedException异常。

Join():用于等待另一个线程结束。

Notify():唤醒一个处于等待状态的线程。在调用这个方法的时候并不能确切唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。

AllNotify():唤醒所有处于等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让他们竞争。


总结:

          需要注意的是,无论synchronized关键字夹在方法上还是对象上,他取得的锁都是对象,而不是一段代码或函数。同步是一种高开销的操作,应尽量减少需要同步的内容。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 42
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值