关闭

线程同步synchronized

250人阅读 评论(0) 收藏 举报

synchronized只是保证在同一个时刻,其他线程不能访问锁定的资源,但是其他方法或者是变量不能锁定控制的

 

synchronized(obj){
	...
	//此处的代码就是同步代码块
}

上面语法格式中synchronized后括号里的obj就是同步监视器,上面代码的含义是:线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。

任何时刻只能有一个线程可以获取对同步监视器的锁定,当同步代码块执行完之后,该线程会释放对该同步监视器的锁定。

同步监视器的目的:阻止两个线程对同一个共享资源进行并发访问,因此通常推荐使用可能被并发访问的共享资源充当同步监视器

 

使用synchronized关键字来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无须显示指定同步监视器,同步方法的同步监视器是this,也就是该对象本身

使用同步方法可以非常方便的实现线程安全类,线程安全类具有如下特征:

1、该类的对象可以被多个线程安全的访问

2、每个线程调用该对象的任意方法之后都将得到正确结果

3、每个线程调用该对象的任意方法之后,该对象的状态依然保持合理状态。

 

synchronized可以修饰方法、代码块,但是不能修饰构造器和属性等。

 

解决死锁办法之一:
1、将锁的粒度放粗一点(一口气锁住所有资源)

public class TraditionalThreadSynchronized {

	public static void main(String[] args) {
		new TraditionalThreadSynchronized().init();
	}
	
	private void init(){
		final Outputer outputer = new Outputer();
		new Thread(new Runnable(){
			@Override
			public void run() {
				while(true){
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					outputer.output("zhangxiaoxiang");
				}
				
			}
		}).start();
		
		new Thread(new Runnable(){
			@Override
			public void run() {
				while(true){
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					outputer.output3("lihuoming");
				}
				
			}
		}).start();
		
	}

	static class Outputer{
		
		public void output(String name){
			int len = name.length();
			synchronized (Outputer.class) 
			{
				for(int i=0;i<len;i++){
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}
		}
		
		public synchronized void output2(String name){
			int len = name.length();
			for(int i=0;i<len;i++){
				System.out.print(name.charAt(i));
			}
			System.out.println();
		}
		
		public static synchronized void output3(String name){
			int len = name.length();
			for(int i=0;i<len;i++){
				System.out.print(name.charAt(i));
			}
			System.out.println();
		}	
	}
}

 

备注:如果同步方法是“静态方法”,则同步监视器应该是“字节码

 

可以简单的模拟死锁的情况

public class TestDeadLockMain {
	public static void main(String[]args){
		TestDeadLock t1 = new TestDeadLock();
		TestDeadLock t2 = new TestDeadLock();
		t1.setFlag(0);
		t2.setFlag(1);
		Thread thread1 = new Thread(t1);
		Thread thread2 = new Thread(t2);
		thread1.start();
		thread2.start();
	}
}

package hb.thread;

public class TestDeadLock implements Runnable {

	public int flag = 1;
	public Object obj1 = new Object();
	public Object obj2 = new Object();
	
	public void setFlag(int flag){
		this.flag = flag;
	}
	
	@Override
	public void run() {
		if(0 == flag){
			synchronized(obj1){
				try {
					System.out.println("flag = " + flag);
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(obj2){
					System.out.println("second obj2");
				}
			}
		}
		if(1 == flag){
			synchronized(obj2){
				try {
					System.out.println("flag = " + flag);
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(obj1){
					System.out.println("second obj1");
				}
			}
		}
	}

}

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:325207次
    • 积分:8907
    • 等级:
    • 排名:第2227名
    • 原创:1096篇
    • 转载:14篇
    • 译文:0篇
    • 评论:5条
    最新评论