【Java】【多线程】同步方法和同步代码块、死锁

原创 2018年04月16日 21:19:37

转载:https://blog.csdn.net/u010002184/article/details/72566874?locationNum=11&fps=1

一、java的内置锁

        每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。

    获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。

    java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,知道线程B释放这个锁,如果B线程不释放这个锁,那么A线程将永远等待下去。

  • java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象非静态实例方法,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的。

二、同步

1、同步代码块

  • 用synchronized关键字加上一个锁对象来定义一段代码, 这就叫同步代码块
  • 多个同步代码块如果使用相同的锁对象, 那么他们就是同步的。锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象
class Printer {
	Demo d = new Demo();
	public static void print1() {
	    synchronized(d){	           //锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象
		System.out.print("黑");
		System.out.print("马");
		System.out.print("程");
		System.out.print("序");
		System.out.print("员");
		System.out.print("\r\n");
		}
	}
	
	public static void print2() {	
	    synchronized(d){	
		System.out.print("传");
		System.out.print("智");
		System.out.print("播");
		System.out.print("客");
		System.out.print("\r\n");
		}
	}
}

2、同步方法

  • 使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的

  • 非静态方法的锁机制为this
  • 静态方法的锁机制为字节码对象,类名.class
class Printer {
    public static void print1() {
	synchronized(Printer.class){				//锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象
		System.out.print("黑");
		System.out.print("马");
		System.out.print("程");
		System.out.print("序");
		System.out.print("员");
		System.out.print("\r\n");
		}
	}	
	/*
	* 非静态同步函数的锁是:this
	* 静态的同步函数的锁是:字节码对象
	*/
    public static synchronized void print2() {	
	System.out.print("传");
		System.out.print("智");
		System.out.print("播");
		System.out.print("客");
		System.out.print("\r\n");
		}
	}

转载1:https://blog.csdn.net/zhenwodefengcaii/article/details/54601098(棒)

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

     1、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
   2、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
  3、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
    4、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
    5、以上规则对其它对象锁同样适用.

其他更多解释,直接看链接~~~~


转载2:https://www.cnblogs.com/sgzs/archive/2017/12/01/7943647.html

深刻通俗理解:

虽然写法不同,但实际上,只有一种,就是【同步代码块】。这是核心核心核心。同步方法也是同步代码块。

同步就是:一个对象同一时间只能为一个同步代码块服务

同步代码块需要传递的对象(锁对象):就是锁住这个对象,表示这个对象正在为我服务,其他人不能用(非synchronized代码块、方法除外)。

同步方法:就是同步代码块,同步锁对象是this

同步静态方法:就是同步代码块,同步锁对象是类的class对象(Demo类里的静态方法锁对象就是Demo.class)

OK了,这就是同步原理。再说简单点(当一个对象被锁住之后,在该代码块之外去使用此对象的方法,只要遇到同步代码块,就会进入等待状态)


四、死锁

多线程同步的时候, 如果同步代码嵌套, 使用相同锁, 就有可能出现死锁。

第一个线程中需获取第二个线程,第二个线程执行时需获取第一个线程,而此时第一个线程还没执行完没被释放,此时就陷入了僵持状态,进入死锁。


五、回顾以前说过的线程安全问题

    * 看源码:Vecto,StringBuffer,Hashtable,Collections.synchroinzed(xxx)

  •  Vector是线程安全的,ArrayList是线程不安全的;
  • StringBuffer是线程安全的,StringBuilder是线程不安全的;
  •  Hashtable是线程安全的,HashMap是线程不安全的。



版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/love_Aym/article/details/79965406

多线程14__Java同步代码块,同步方法

同步代码块 参见http://www.cnblogs.com/sunzn/archive/2013/02/13/2910895.html,这里改为限制循环次数50次: new Thread() ...
  • aduovip
  • aduovip
  • 2015-04-25 13:17:53
  • 1430

java同步方法和同步代码块

java synchronized详解 记下来,很重要。 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。      一、当两个并...
  • zhenwodefengcaii
  • zhenwodefengcaii
  • 2017-01-18 14:45:38
  • 7888

java 多线程学习笔记2-同步代码块,死锁

1、多线程-同步代码块:synchronized     当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步。     如...
  • gaopinqiang
  • gaopinqiang
  • 2016-12-18 15:08:04
  • 721

java同步方法和同步代码块的区别

同步代码块: package threads.ex1; class KitchenSync { private int[] intArray = new int[10]; void reve...
  • feier7501
  • feier7501
  • 2014-03-25 21:13:27
  • 18281

java同步代码块和同步方法的区别

  • u010739551
  • u010739551
  • 2016-03-17 11:01:51
  • 546

同步方法与同步代码块的区别?

搜刮总结核心知识点: Synchronized 方法控制对类成员的访问:每个类实例对应一把锁,每个synchronized方法都必须获得调用该方法的实例的锁方能执行,否则所属线程阻塞,方法一旦执行,...
  • quniandongtian
  • quniandongtian
  • 2014-03-03 22:00:52
  • 3340

《多线程编程》学习之五:synchronized同步语句块,静态同步synchronized方法与synchronized(类名.class)代码块

在介绍同步语句块之前,先做一个实验,验证多个线程调用同一个同步方法是随机的。 例子一: 1)MyList.java 2)测试:         可见,在同步方法中的代码是同步打印的,但线程A和...
  • studyhxz
  • studyhxz
  • 2016-10-20 13:28:16
  • 875

同步方法与同步代码块的区别

synchronized 方法控制类成员的访问:每个类实力对应一把锁,每个synchronized方法都必须获得调用改方法的实例的所才能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返...
  • neutrojan
  • neutrojan
  • 2015-07-21 16:36:26
  • 4708

同步代码块、同步方法、锁总结

同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块,其语法如下: synchronized(obj){ //同步...
  • weixin_36937689
  • weixin_36937689
  • 2017-06-07 22:34:51
  • 686

同步方法与同步块的区别

java使用synchronized同步,分为四种情况:   实例方法同步   实例方法中同步块   静态方法同步   静态方法中同步块 我们从两个方面来说他们的不同,一个是...
  • SilenceCarrot
  • SilenceCarrot
  • 2016-09-02 18:16:49
  • 11255
收藏助手
不良信息举报
您举报文章:【Java】【多线程】同步方法和同步代码块、死锁
举报原因:
原因补充:

(最多只允许输入30个字)