线程同步synchronized

原创 2013年12月04日 09:49:48

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");
				}
			}
		}
	}

}

 

JAVA学习笔记(2)_____线程同步锁(synchronized)模拟火车售票窗口

java中cpu分给每个线程的时间片是随机的并且在java中好多都是多个线程共用一个资源,比如火车卖票,火车票是一定的,但卖火车票的窗口到处都有,每个窗口就相当于一个线程,这么多的线程共用所有的火车票...

Java线程同步:synchronized锁住的是代码还是对象

此文章是转载自大牛博客,原文地址http://blog.csdn.net/xiao__gui/article/details/8188833 在Java中,synchronized关键字是用来控...

java 线程同步:synchronized 关键字

在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。synchronized既可以加在一段代码上,也可以加在...

Java线程同步:synchronized锁住的是代码还是对象

在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。Synchronized既可以对代码块使用,也可以加在整...

JavaSE 线程同步之synchronized

Java中每一个

java线程同步——条件对象+synchronized 关键字

【0】README0.1) 本文描述转自 core java volume 1, 源代码为原创,旨在理解 java线程同步——竞争条件的荔枝+锁对象 的相关知识; 0.2)for full sou...

10. 11. 1. 线程同步 Test Synchronized method

public class TestSynchronized { int taskID;//任务ID public static void print(String msg){//定义一个...

Java线程同步 (synchronized wait notify)

注:wait notify 都是Object的方法   同步(阻塞) :是一种防止对共享资源访问导致的数据不一致的一种模式。 详细请参看操作系统。 在Java中,由于对多线程的支持,对同步...

synchronized线程同步锁

在Java中,synchronized关键字是用来控制线程同步的。synchronized既可以加在一段代码上,也可以加在方法上。下面主要来讲讲对象锁的概念,通过例子帮助读者理解:class Test...

Java线程同步,synchronized锁住的是代码还是对象

作者:叉叉哥   转载自:http://blog.csdn.net/xiao__gui/article/details/8188833  在Java中,synchronized关键字是用来控制线程同...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:线程同步synchronized
举报原因:
原因补充:

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