sychronized用法_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > sychronized用法

sychronized用法

 2013/11/20 0:25:29  junzai  程序员俱乐部  我要评论(0)
  • 摘要:Synchronized可分为synchronized方法和synchronized块。synchronized方法通常是在public之后返回值之前如:publicsynchronizedvoidA()而synchronized块则是在方法里面,如:publicvoidB(){Synchronized(object){……}}一、两个线程并发访问synchronized块时,一次只有一个线程能够访问,另一个线程只能等待当前线程访问完并释放synchronized块才能访问
  • 标签:用法 Ron

class="p0" style="margin-top: 0pt; margin-bottom: 0pt;">Synchronized可分为synchronized方法和synchronized块。synchronized方法通常是在public之后返回值之前如:public?synchronized?void?A()

synchronized块则是在方法里面,如:

public?void?B(){

Synchronized(object){

……

}

}

一、两个线程并发访问synchronized块时,一次只有一个线程能够访问,另一个线程只能等待当前线程访问完并释放synchronized块才能访问。

/**
 * 这个例子是想说明两个并发执行的线程需要同时访问一个对象的synchronized代码块时,同意时刻只有一个进程在执行,
 * 一个进程在执行时,另一个进程必须等待当前进程执行完
 * @author zzj
 *
 */
public class Thread1 extends Thread{

	public static void main(String[] args) {
		Thread1 t1 = new Thread1();//注意这里,因为ta,tb是两个并发执行的线程
		Thread ta = new Thread(t1,"A");
		Thread tb = new Thread(t1,"B");
		ta.start();
		tb.start();
	}
	
	public void run(){
		synchronized(this){
			for(int i=0;i<5;i++){
				System.out.println(Thread.currentThread().getName()+"锁释放"+i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

?结果:

A锁释放0
A锁释放1
A锁释放2
A锁释放3
A锁释放4
B锁释放0
B锁释放1
B锁释放2
B锁释放3
B锁释放4

?

二、当一个线程访问synchronized块时,另一个线程仍可以访问该objectsynchronized同步代码块

?

/**
 * 这个例子是要说明一个进程访问object的synchronized同步代码块时,其他进程可以同时访问object的非synchronized块
 * @author zzj
 *
 */
public class Thread2{

	public static void main(String[] args) {
		final Thread2 t2 = new Thread2();//注意这里,因为ta,tb是两个并发执行的线程
		Thread ta = new Thread(new Runnable(){public void run(){ t2.A();}},"A");
		Thread tb = new Thread(new Runnable(){public void run(){ t2.B();}},"B");
		ta.start();
		tb.start();
	}
	
	//synchronized代码块
	public void A(){
		synchronized(this){
			for(int i=0;i<5;i++){
				System.out.println(Thread.currentThread().getName()+":"+i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	//非synchronized代码块
	public void B(){
		for(int i=0;i<5;i++){
			System.out.println(Thread.currentThread().getName()+":"+i);
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

?结果:

A:0
B:0
A:1
B:1
A:2
B:2
B:3
A:3
B:4
A:4

?

三、当一个线程访问objectsynchronized块时,其他线程对object其他synchronized代码块的访问也讲被阻塞

?

/**
 * 这个例子是想说明两个并发的线程如果一个在访问synchronized同步代码块,其他线程对所有其他sychronized块的访问会被阻塞
 * @author zzj
 *
 */
public class Thread3 extends Thread{

	public static void main(String[] args) {
		final Thread3 t3 = new Thread3();//注意这里,因为ta,tb是两个并发执行的线程
		Thread ta = new Thread(new Runnable(){public void run(){ t3.A();}},"A");
		Thread tb = new Thread(new Runnable(){public void run(){ t3.B();}},"B");
		ta.start();
		tb.start();
	}
	
	//synchronized代码块
	public void A(){
		synchronized(this){
			for(int i=0;i<5;i++){
				System.out.println(Thread.currentThread().getName()+":"+i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	//非synchronized代码块
	public void B(){
		synchronized(this){
			for(int i=0;i<5;i++){
				System.out.println(Thread.currentThread().getName()+":"+i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

?结果:

A:0
B:0
A:1
B:1
A:2
B:2
B:3
A:3
B:4
A:4

??

四、当一个线程访问object的一个synchronized同步代码块时,它就获得了同步对象锁,其他所有线程对该object对象的所有同步代码部分访问都暂时被阻塞(不一定是synchronized同步代码块,可能是synchronized方法)

/**
 * 这个例子是想说明一个进程在执行synchronized同步代码块时,其他进程要访问同步代码部分
 * (不论是synchronized块还是方法都将被阻塞)
 * @author zzj
 *
 */
public class Thread4 {

	public static void main(String[] args) {
		final Thread4 t4 = new Thread4();//注意这里,因为ta,tb是两个并发执行的线程
		Thread ta = new Thread(new Runnable(){public void run(){ t4.A();}},"A");
		Thread tb = new Thread(new Runnable(){public void run(){ t4.B();}},"B");
		ta.start();
		tb.start();
	}
	
	//synchronized代码块
	public void A(){
		synchronized(this){
			for(int i=0;i<5;i++){
				System.out.println(Thread.currentThread().getName()+":"+i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	//非synchronized代码块
	public synchronized void B(){
			for(int i=0;i<5;i++){
				System.out.println(Thread.currentThread().getName()+":"+i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
	}

}

?结果:

A:0
B:0
A:1
B:1
A:2
B:2
B:3
A:3
B:4
A:4

?

五、以上规则对其他对象锁同样适用。

?

仔细看1234的区别。

?

总的说来,synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object?reference(对象引用)、static函数和class?literals(类名称字面常量)身上。

?

我们需要明确几点:

A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。

B.每个对象只有一个锁(lock)与之相关联。

C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

<!--EndFragment-->

发表评论
用户名: 匿名