`
liulanghan110
  • 浏览: 1063948 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

synchronized

    博客分类:
  • JAVA
阅读更多

synchronized 关键字的作用一个词概括就是:线程同步。它可以将将对象或者Class加锁,用来防止两个线程同时访问一个数据。

 

看如下代码:

 

package com.test.runnable;

public class DoSomething implements Runnable{
	private String name;
	
	public DoSomething(String name){
		this.name = name;
	}

	public void run(){
		for(int i = 0; i < 5;i++){
				System.out.println(name+":"+i);
		}
		
	}
}

 

package com.test.runnable;


public class TestRunnable {
	public static void main(String argc[]){
		DoSomething ds1 = new DoSomething("张三");
		DoSomething ds2 = new DoSomething("李四");
		Thread t1 = new Thread(ds1);
		Thread t2 = new Thread(ds2);
		t1.start();
		t2.start();
	}
}

 输出结果为:

张三:0

李四:0

张三:1

李四:1

张三:2

张三:3

张三:4

李四:2

李四:3

李四:4

可以发现并不是张三输出完了再输出李四。

然后给输出的语句块加上synchronized 关键字,如下:

 

package com.test.runnable;

public class DoSomething implements Runnable{
	private String name;
	
	public DoSomething(String name){
		this.name = name;
	}

	public void run(){
		synchronized(this){
			for(int i = 0; i < 5;i++){
				System.out.println(name+":"+i);
			}
		}
	}
}

 

 

但发现,再次运行发现还是乱序,原因是synchronized(this)获得的是对象锁,t1运行时获得的是ds1对象的锁,t2运行时获得的是ds2的对象锁,两个互不干扰,所以此时synchronized无效。要时synchronized有效,可以将代码改成如下:

 

package com.test.runnable;


public class TestRunnable {
	public static void main(String argc[]){
		DoSomething ds1 = new DoSomething("张三");
		DoSomething ds2 = new DoSomething("李四");
		Thread t1 = new Thread(ds1);
		Thread t2 = new Thread(ds1);
		t1.start();
		t2.start();
	}
}

 

也可以将锁的范围由对象改为类,这样t1运行时获得的是DoSomething.class的锁,t2运行时再获得 DoSomething.class的锁时发现不能获得,等待t1的synchronized块运行完释放锁时才能得到。代码如下:

package com.test.runnable;

public class DoSomething implements Runnable{
	private String name;
	
	public DoSomething(String name){
		this.name = name;
	}

	public void run(){
		synchronized(DoSomething.class){
			for(int i = 0; i < 5;i++){
				System.out.println(name+":"+i);
			}
		}
	}
}

 

当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其他synchronized(this)同步代码块得访问将被阻塞。

 

看如下代码:

package com.test.runnable;

public class DoSomething implements Runnable{
	private String name;

	
	public DoSomething(String name){
		this.name = name;
	}
	
	public void doA(){
		synchronized(this){
			for(int i = 0; i < 5;i++){
				System.out.println("做A事情:"+name+":"+i);
			}
		}
	}

	public void doB(){
		synchronized(this){
			for(int i = 0; i < 5;i++){
				System.out.println("做B事情:"+name+":"+i);
			}
		}
	}
	public void run(){
		doA();
		doB();
	}
}

 

package com.test.runnable;


public class TestRunnable {
	public static void main(String argc[]){
		DoSomething ds1 = new DoSomething("张三");
		Thread t1 = new Thread(ds1);
		Thread t2 = new Thread(ds1);
		t1.start();
		t2.start();
	}
}

 当t1运行到doB时,理论上doA已经解锁了。这时t2可以运行doA代码。但实际上,由于t1此时对象锁还没释放,t2也不能获得对象锁,也不能运行doA的代码。只能等t1运行完doB释放对象锁了,t2才能开始运行doA

 

 

                

 

 

  • 大小: 13.8 KB
0
1
分享到:
评论
1 楼 hzieept 2014-08-22  
我给博主总结一下。
本文实验了 synchronized method, synchronized object, synchronized class 的区别。

相关推荐

Global site tag (gtag.js) - Google Analytics