Java synchronized同步方法和同步块总结

标签: java synchronized 同步 | 发表时间:2014-03-17 19:48 | 作者:beston
出处:http://www.iteye.com
今天做了一些实验,把Java synchronized同步方法和同步块总结一下,欢迎拍砖!

Java synchronized同步方法和同步块总结:

1、非静态 同步方法:
synchronized method() {...} 锁对象的所有同步方法
一个进程进入某对象同步方法后,其它线程不能同时访问这个对象中任何一个同步方法


/**************************************************************************************** 
 Copyright © 2014 Your Company/Org. All rights reserved.<br> 
 Reproduction or transmission in whole or in part, in any form or<br>
 by any means, electronic, mechanical or otherwise, is prohibited<br>
 without the prior written consent of the copyright owner. <br>
 ****************************************************************************************/
package com.beston.concurrency.synchronization;

/** 
 * @ClassName: SyncMethod 
 * @Description: 同步方法    synchronized syncMethod(){...}
 * 作用域:某个对象实例内,可以防止多个线程同时访问这个对象的synchronized方法
 * 如果一个对象有多个synchronized方法,只要一个线 程访问了其中的一个synchronized方法,
 * 其它线程不能同时访问这个对象中任何一个synchronized方法.这时,不同的对象实例的 synchronized方法是不相干扰的。
 * 也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;  
 * @author beston 
 * @date 2014年3月17日 下午4:19:32 
 * @version v1.0
 *  
 */
public class SyncMethod {
	
	public static void main(String[] args) {
		MethodObj obj = new MethodObj();
		//线程1执行  hello()和syncmethod1()方法 
		new Thread(new Runnable1(obj)).start();
		//线程2执行  hello()和syncmethod2()方法 
		new Thread(new Runnable2(obj)).start();
	}

}
/** 
 * @ClassName: Runnable1 
 * @Description: 执行  hello()和syncmethod1()方法 
 * @author beston 
 * @date 2014年3月17日 下午4:29:49 
 * @version v1.0
 *  
 */ 
class Runnable1 implements Runnable{
	private MethodObj obj;
	
	public Runnable1(MethodObj obj){
		this.obj= obj;
	}
	public  void run(){	
		obj.hello();
		obj.syncmethod1();
		
	}
}

/** 
 * @ClassName: Runnable2 
 * @Description: 执行  hello()和syncmethod2()方法
 * @author beston 
 * @date 2014年3月17日 下午4:29:07 
 * @version v1.0
 *  
 */ 
class Runnable2 implements Runnable{
	private MethodObj obj;
	
	public Runnable2(MethodObj obj){
		this.obj= obj;
	}
	public  void run(){
		obj.hello();
		obj.syncmethod2();
	}
}

class MethodObj{
	
	/** 
	 * @Title: hello 
	 * @Description: 非同步,不会被锁
	 */
	public void hello(){
		System.out.println(Thread.currentThread().getName()+" hello!");

	}
	
	/** 
	 * @Title: syncmethod1 
	 * @Description: 同步方法1,被第一个持有该对象的线程占用5秒
	 */
	public synchronized void syncmethod1(){
		System.out.println(Thread.currentThread().getName()+" 占用 syncmethod1() 5秒");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/** 
	 * @Title: syncmethod2 
	 * @Description: 同步方法2
	 */
	public synchronized void syncmethod2(){
		System.out.println(Thread.currentThread().getName()+" syncmethod2()");
	}
}

2、非静态 同步块:
2.1
method(){
    synchronized (this){..}  锁对象的所有同步方法
}
一个进程进入某对象同步方法后,其它线程不能同时访问这个对象中任何一个同步方法
/**************************************************************************************** 
 Copyright © 2014 Your Company/Org. All rights reserved.<br> 
 Reproduction or transmission in whole or in part, in any form or<br>
 by any means, electronic, mechanical or otherwise, is prohibited<br>
 without the prior written consent of the copyright owner. <br>
 ****************************************************************************************/
package com.beston.concurrency.synchronization;

/** 
 * @ClassName: SyncMethod 
 * @Description: 同步块    synchronized(this){...}
 * 作用域: 锁定 当前对象this 
 * @author beston 
 * @date 2014年3月17日 下午4:19:32 
 * @version v1.0
 *  
 */
public class SyncThis {
	
	public static void main(String[] args) {
		ThisObj obj = new ThisObj();
		//线程1执行  hello()和syncthis1()方法 
		new Thread(new Runnable3(obj)).start();
		//线程2执行  hello()和syncthis2()方法 
		new Thread(new Runnable4(obj)).start();
	}

}
/** 
 * @ClassName: Runnable3 
 * @Description: 执行  hello()和syncthis1()方法 
 * @author beston 
 * @date 2014年3月17日 下午4:29:49 
 * @version v1.0
 *  
 */ 
class Runnable3 implements Runnable{
	private ThisObj obj;
	
	public Runnable3(ThisObj obj){
		this.obj= obj;
	}
	public  void run(){	
		obj.hello();
		obj.syncthis1();
		
	}
}

/** 
 * @ClassName: Runnable4 
 * @Description: 执行  hello()和syncthis2()方法
 * @author beston 
 * @date 2014年3月17日 下午4:29:07 
 * @version v1.0
 *  
 */ 
class Runnable4 implements Runnable{
	private ThisObj obj;
	
	public Runnable4(ThisObj obj){
		this.obj= obj;
	}
	public  void run(){
		obj.hello();
		obj.syncthis2();
	}
}

class ThisObj{
	/** 
	 * @Title: hello 
	 * @Description: 非同步,不会被锁
	 */
	public void hello(){
		System.out.println(Thread.currentThread().getName()+" hello!");

	}
	
	/** 
	 * @Title: syncthis1 
	 * @Description: 同步块1,被第一个持有该对象的线程占用5秒
	 */
	public void syncthis1(){
		synchronized(this){
			System.out.println(Thread.currentThread().getName()+" 占用 syncthis1() 5秒");
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	/** 
	 * @Title: syncthis2 
	 * @Description: 同步块2
	 */
	public void syncthis2(){
		synchronized(this){
			System.out.println(Thread.currentThread().getName()+" syncthis2()");
		}
		
	}
}

2.2
Object obj = new Object();
method(){
    synchronized (obj){..}  锁住该代码块
}
锁定非自身(this)的其他对象(如this的成员),则只锁住该代码块,本类其他同步方法不受影响
/**************************************************************************************** 
 Copyright © 2014 Your Company/Org. All rights reserved.<br> 
 Reproduction or transmission in whole or in part, in any form or<br>
 by any means, electronic, mechanical or otherwise, is prohibited<br>
 without the prior written consent of the copyright owner. <br>
 ****************************************************************************************/
package com.beston.concurrency.synchronization;

/** 
 * @ClassName: SyncBlock 
 * @Description: 同步块 synchronized(obj){...} 
 * 锁定非自身(this)的其他对象,则只锁住该代码块,其他同步方法不受影响
 * @author beston 
 * @date 2014年3月17日 下午5:02:16 
 * @version v1.0
 *  
 */
public class SyncBlock {
	public static void main(String[] args) {
		BlockObj obj = new BlockObj();
		//线程1执行  hello()和syncblock1()方法 
		new Thread(new Runnable5(obj)).start();
		//线程2执行  hello()和syncblock1(),syncblock2()方法 
		new Thread(new Runnable6(obj)).start();
	}

}
/** 
 * @ClassName: Runnable5 
 * @Description: 执行  hello()和syncblock1()方法 
 * @author beston 
 * @date 2014年3月17日 下午4:29:49 
 * @version v1.0
 *  
 */ 
class Runnable5 implements Runnable{
	private BlockObj obj;
	
	public Runnable5(BlockObj obj){
		this.obj= obj;
	}
	public  void run(){	
		obj.hello();
		obj.syncblock1();
		
	}
}

/** 
 * @ClassName: Runnable6 
 * @Description: 执行  hello()和syncblock1(),syncblock2()方法 
 * @author beston 
 * @date 2014年3月17日 下午4:29:07 
 * @version v1.0
 *  
 */ 
class Runnable6 implements Runnable{
	private BlockObj obj;
	
	public Runnable6(BlockObj obj){
		this.obj= obj;
	}
	public  void run(){
		obj.hello();
		obj.syncblock2(); 
		obj.syncblock1(); 
		
	}
}

class BlockObj{
	Byte[] b = new Byte[0];
	Object a = new Object();
	int i = 0;//非对象 不能放到synchronized()括号中
	/** 
	 * @Title: hello 
	 * @Description: 非同步,不会被锁
	 */
	public void hello(){
		System.out.println(Thread.currentThread().getName()+" hello!");

	}
	
	/** 
	 * @Title: syncblock1 
	 * @Description: 同步块,进入该方法线程占用5秒
	 */
	public void syncblock1(){
		synchronized(a){
			System.out.println(Thread.currentThread().getName()+" 占用 syncblock1() 5秒");
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	/** 
	 * @Title: syncblock2 
	 * @Description: 同步块
	 */
	public void syncblock2(){
		synchronized(b){
			System.out.println(Thread.currentThread().getName()+" syncblock2()");
		}
		
	}
}


3、静态 同步方法
static synchronized method() {...}
一个进程进入类静态同步方法后,其它线程不能同时访问这个类中静态同步方法和静态同步块,其他非静态同步方法和非静态同步块不受影响
/**************************************************************************************** 
 Copyright © 2014 Your Company/Org. All rights reserved.<br> 
 Reproduction or transmission in whole or in part, in any form or<br>
 by any means, electronic, mechanical or otherwise, is prohibited<br>
 without the prior written consent of the copyright owner. <br>
 ****************************************************************************************/
package com.beston.concurrency.synchronization;

import java.util.logging.Logger;

/**
 * @ClassName: SynStaticMethod
 * @Description: 结论: 不同线程访问同一个类的静态同步方法时, 线程间是互斥的.其他非静态同步块和同步方法不受影响
 * @author beston
 * @date 2014年3月17日 下午6:02:41
 * @version v1.0
 * 
 */
public class SynStaticMethod {

	// 线程1
	static class T1 implements Runnable {
		SynStaticMethod s;

		public T1(SynStaticMethod sameObj) {
			this.s = sameObj;
		}

		// 线程1访问静态同步方法
		public void run() {
			SynStaticMethod.syn();
		}
	}

	// 线程2
	static class T2 implements Runnable {
		SynStaticMethod s;

		public T2(SynStaticMethod sameObj) {
			this.s = sameObj;
		}

		// 线程2访问静态同步方法
		public void run() {
			//SynStaticMethod.static2();不会阻塞
			//SynStaticMethod.syn2();
			//new SynStaticMethod().synInstance3();
			//new SynStaticMethod().syn();
			//SynStaticMethod.syn();
			
		}
	}

	// 对象的静态同步方法
	public static synchronized void syn() {
		String threadStr = Thread.currentThread().getName();
		
		try {
			System.out.println(threadStr + "正在静态访问同步方法syn()!!!");
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	
	// 对象的静态同步方法
	public static synchronized void syn2() {
		String threadStr = Thread.currentThread().getName();
		
		try {
			System.out.println(threadStr + "正在静态访问同步方法syn2()!!!");
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	
	// 对象的静态同步方法
	public synchronized void synInstance3() {
		String threadStr = Thread.currentThread().getName();
		
		try {
			System.out.println(threadStr + "正在静态访问同步方法synInstance3()!!!");
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}

	// 对象的静态方法2
	public static void static2() {
		String threadStr = Thread.currentThread().getName();
		
		try {
			System.out.println(threadStr + "正在静态访问方法static2()!!!");
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}

	public static void main(String[] args) {
		// 这是多线程要访问的同一个对象
		SynStaticMethod sameObj1 = new SynStaticMethod();
		SynStaticMethod sameObj2 = new SynStaticMethod();

		// 线程1,线程2访问静态同步方法
		Thread t1 = new Thread(new T1(sameObj1));
		Thread t2 = new Thread(new T2(sameObj2));

		t1.start();
		t2.start();
	}
}

4、静态 同步块
method(this.class){
    synchronized (obj){..}
}
一个进程进入类静态同步块后,其它线程不能同时访问这个类中所有静态同步方法和静态同步块,其他非静态同步方法和非静态同步块不受影响
/**************************************************************************************** 
 Copyright © 2014 Your Company/Org. All rights reserved.<br> 
 Reproduction or transmission in whole or in part, in any form or<br>
 by any means, electronic, mechanical or otherwise, is prohibited<br>
 without the prior written consent of the copyright owner. <br>
 ****************************************************************************************/
package com.beston.concurrency.synchronization;

import java.util.logging.Logger;

/**
 * @ClassName: SynStaticClass
 * @Description: 不同线程访问类的所有同步块静态方法和静态同步方法时, 线程间是互斥的.其他非静态同步块和同步方法不受影响
 * @author beston
 * @date 2014年3月17日 下午6:02:41
 * @version v1.0
 * 
 */
public class SynStaticClass {

	// 线程1
	static class T1 implements Runnable {
		SynStaticClass s;

		public T1(SynStaticClass sameObj) {
			this.s = sameObj;
		}

		// 线程1访问静态同步方法
		public void run() {
			SynStaticClass.syn();
		}
	}

	// 线程2
	static class T2 implements Runnable {
		SynStaticClass s;

		public T2(SynStaticClass sameObj) {
			this.s = sameObj;
		}

		// 线程2访问静态同步方法
		public void run() {
			new SynStaticClass().synInstance4();//不会被阻塞
			//new SynStaticClass().syn(); //会阻塞
			//new SynStaticClass().syn3(); //会阻塞
			//SynStaticClass.syn3(); //阻塞
			//SynStaticClass.syn2(); //阻塞
			//SynStaticClass.syn();  //阻塞
		}
	}

	// 对象的同步块静态方法
	public static void syn() {
		synchronized(SynStaticClass.class){
			String threadStr = Thread.currentThread().getName();
			try {
				System.out.println(threadStr + "正在静态访问同步方法syn()!!!");
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}	
	}

	// 对象的同步块静态方法2
	public static void syn2() {
		synchronized (SynStaticClass.class) {
			String threadStr = Thread.currentThread().getName();
			try {
				System.out.println(threadStr + "正在静态访问同步方法syn2()!!!");
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	// 对象的静态同步方法3
	public static synchronized void syn3() {
			String threadStr = Thread.currentThread().getName();
			try {
				System.out.println(threadStr + "正在静态访问同步方法syn3()!!!");
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}
	
	// 对象的同步方法3
	public synchronized void synInstance4() {
			String threadStr = Thread.currentThread().getName();
			try {
				System.out.println(threadStr + "正在访问实例同步方法synInstance4()!!!");
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}

	public static void main(String[] args) throws InterruptedException {
		// 这是多线程要访问的同一个类
		SynStaticClass sameObj1 = new SynStaticClass();
		SynStaticClass sameObj2 = new SynStaticClass();

		// 线程1,线程2访问静态同步方法
		Thread t1 = new Thread(new T1(sameObj1));
		Thread t2 = new Thread(new T2(sameObj2));

		t1.start();
		Thread.sleep(100);
		t2.start();
	}
}


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [java synchronized 同步] 推荐:

Java同步块(Synchronized Blocks)

- - 并发编程网 - ifeve.com
原文链接  作者:Jakob Jenkov  译者:李同杰. Java 同步块(synchronized block)用来标记方法或者代码块是同步的. Java同步关键字(synchronzied). Java 同步关键字( synchronized ). Java中的同步块用synchronized标记.

Java synchronized同步方法和同步块总结

- - 编程语言 - ITeye博客
今天做了一些实验,把Java synchronized同步方法和同步块总结一下,欢迎拍砖. Java synchronized同步方法和同步块总结:. synchronized method() {...} 锁对象的所有同步方法. 一个进程进入某对象同步方法后,其它线程不能同时访问这个对象中任何一个同步方法.

Java线程同步中关键字synchronized详述

- - 编程语言 - ITeye博客
synchronized关键可以修饰函数、函数内语句. 无论它加上方法还是对象上,它取得的锁都是对象,而不是把一段代码或是函数当作锁. 1,当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一段时间只能有一个线程得到执行,而另一个线程只有等当前线程执行完以后才能执行这块代码.

[转]java synchronized详解

- - 小彰
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.      一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行. 另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块.

文章: Java SE1.6中的Synchronized

- - InfoQ cn
在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,本文详细介绍了Java SE1.6中为了减少获得锁和释放锁带来的性能消耗,而引入的偏向锁和轻量级锁,以及锁的存储结构和升级过程.

Java多线程之synchronized

- - CSDN博客推荐文章
这里通过三个测试类阐述了synchronized应用的不同场景. 首先是最基本的synchronized Method的使用.  * @see 概述:Java中的每个对象都有一个锁(lock)或者叫做监视器(monitor) .  * @see 说明:当synchronized关键字修饰一个方法时,则该方法为同步方法 .

java 并发编程 synchronized

- - Java - 编程语言 - ITeye博客
同步原语--synchronized. synchronized(class)很特别,它会让另一个线程在任何需要获取class做为monitor的地方等待.class与this做为不同的监视器可以同时使用,不存在一个线程获取了class,另一个线程就不能获取该class的一切实例.. ->线程各自获取monitor,不会有等待..

Java中Synchronized的用法

- - CSDN博客推荐文章
synchronized是Java中的关键字,是一种同步锁. 它修饰的对象有以下几种:. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;.

java-synchronized修饰方法释疑

- - ITeye博客
java里面用synchronized修饰方法时:. 对于 同一个对象的来说. 所有synchronized修饰的方法会 相互阻塞(即调用了某一个synchronized修饰的方法,则其余所有synchronized修饰的方法的调用都会阻塞,需要等待获取内置锁). 没有synchronized修饰的方法的则不会阻塞.

[原]Java多线程中的synchronized、volatile和无锁编程

- - Snowball
新建状态(New):新创建了一个线程对象. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法. 该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行.