用synchronized关键字加锁

官方介绍synchronized作用:

   同步方法支持一种简单的策略来防止线程干扰和内存一致性错误:如果一个对象对多个线程可见,则用改对象变量的所有读取或写入都是通过同步方法完成的。

一句话来说:

能够保证一段时间内只有一个线程执行该段代码,以达到并发安全的效果,是一种悲观锁。

 

看2段代码:

    

	public static void main(String[] args) {
			  for (int i = 0; i <2; i++) {
				  DoThreads dt = new DoThreads(0);
				  Thread dothread = new Thread(dt);
				  dothread.start();
			}
			
		}

public class DoThreads implements Runnable {
	
		private static   int money;
		
		private static final Object  o = new Object();
		public DoThreads(int ages) {
			super();
			this.money = money;
		}
	
		@Override
		public void run() {
			testMethod();
			
		}
			
		public  void testMethod(){
			for (int i = 0; i < 1000; i++) {
				 try {
						Thread.sleep(3);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
				 money=money+10;
			}
		
	
			System.out.println(Thread.currentThread().getName()+"开始"+"===金额"+money);
			 try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			System.out.println(Thread.currentThread().getName()+"结束"+"===金额"+money);
		 
	}
}

输入结果为:

Thread-0开始===金额19870
Thread-1开始===金额19920
Thread-0结束===金额19920
Thread-1结束===金额19920

 

说明2个线程工作的时候金额发生了串号的错误。我们想要的结果是最后金额20000

 

这个时候我们的synchronized该上场了~

 

synchronized有2种用法:

1.对象锁

   包括方法锁和同步代码块锁
 

同步代码块锁:

       synchronized(this){

         需要同步的代码

}

Object  o = new Object();

    synchronized(o){

         需要同步的代码

     }

方法锁:

   public synchronized void testMethod(){

}

2.类锁

   包括修饰静态方法和锁class对象或静态object对象

   修饰静态方法:

public static synchronized void testMethod(){

 需要锁代码 

}

锁class对象或静态object对象

synchronized (DoThreads.class) {

}

 static Object  o = new Object();

    synchronized(o){

         需要同步的代码

     }

 

synchronized有2种用法介绍:

多线程执行同一任务对象,使用对象锁和类锁都能保证线程安全。

多线程执行不同任务对象,使用对象锁不能保证线程安全,使用类锁可以保证线程安全。

synchronize的性质

1 .可重入性

同一个线程的外层方法获得锁之后,内层方法可以直接再次获取该锁

优点 ps:避免死锁  提高封装性

 2 .不可中断性

 一旦同一个锁被别人获得,只能等待别的线程释放该锁才能获得,如果别人不释放,只能永远等下去。

 

synchronize缺陷

1.效率低

2.不够灵活

3.无法知道是否成功获得锁

 

建议使用原则

能用工具包实现就不用synchronize;

能用synchronize实现就用synchronize;

最后再选择lock锁。

使用注意点:

锁对象不能为空,作用域不宜过大,避免死锁

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章