当前位置:首页 > 开发 > 编程语言 > 多线程 > 正文

多线程——同步(synchronized)上

发表于: 2011-12-12   作者:ciding   来源:转载   浏览次数:
摘要: 多线程——同步(synchronized)上   多线程编程中,最关键、最关心的问题应该就是同步问题,这是一个难点,也是核心。 从jdk最早的版本的synchronized、volatile,到jdk 1.5中提供的java.util.concurrent.locks包中的Lock接口(实现有ReadLock,WriteLock,ReentrantLock),多线程的实现也是一步步

多线程——同步(synchronized)上

 

多线程编程中,最关键、最关心的问题应该就是同步问题,这是一个难点,也是核心。

从jdk最早的版本的synchronized、volatile,到jdk 1.5中提供的java.util.concurrent.locks包中的Lock接口(实现有ReadLock,WriteLock,ReentrantLock),多线程的实现也是一步步走向成熟化。

 

同步,它是通过什么机制来控制的呢?第一反应就是锁,这个在学习操作系统与数据库的时候,应该都已经接触到了。在Java的多线程程序中,当多个程序竞争同一个资源时,为了防止资源的腐蚀,给第一个访问资源的线程分配一个对象锁,而后来者需要等待这个对象锁的释放。

 

是的,Java线程的同步,最关心的是共享资源的使用。

 

先来了解一些有哪些线程的共享资源,

从JVM中了解有哪些线程共享的数据是需要进行协调:

1,保存在堆中的实例变量;2,保存在方法区的类变量。

 

而在Java虚拟机加载类的时候,每个对象或类都会与一个监视器相关联,用来保护对象的实例变量或类变量;当然,如果对象没有实例变量,或类没有变量,监视器就什么也不监视了。

 

为了实现上面的说的监视器的互斥性,虚拟机为每一个对象或类都关联了一个锁(也叫隐形锁),这里说明一下,类锁也是通过对象锁来实现的,因为在类加载的时候,JVM会为每一个类创建一个java.lang.Class的一个实例;所以当锁对对象的时候,也就锁住这个类的类对象。

 

另外,一个线程是可以对一个对象进行多次上锁,也就对应着多次释放;它是通过JVM为每个对象锁提供的lock计算器,上一次锁,就加1,对应的减1,当计算器的值为0时,就释放。这个对象锁是JVM内部的监视器使用的,也是由JVM自动生成的,所有程序猿就不用自己动手来加了。

 

介绍完java的同步原理后,我们进入正题,先来说说synchronized的使用,而其它的同步,将在后面的章节中介绍。

 

先来运行一个例子试试。

package thread_test;

/**
 * 测试扩展Thread类实现的多线程程序 
 * 
 * @author ciding 
 * @createTime Dec 7, 2011 9:37:25 AM
 *
 */
public class TestThread extends Thread{ 
	private int threadnum;

	public TestThread(int threadnum) { 
		this.threadnum = threadnum; 
	}
	
	@Override
	public synchronized void run() { 
		for(int i = 0;i<1000;i++){ 
	        		System.out.println("NO." + threadnum + ":" + i );
		}
    	} 
	
    	public static void main(String[] args) throws Exception { 
    		for(int i=0; i<10; i++){
        			new TestThread(i).start();
        			Thread.sleep(1);
    		}
    	} 
}

 

运行结果:

NO.0:887
NO.0:888
NO.0:889
NO.0:890
NO.0:891
NO.0:892
NO.0:893
NO.0:894
NO.7:122
NO.7:123
NO.7:124

上面只是一个片段,说明一个问题而已。

细心的童鞋会发现,NO.0:894后面是NO.7:122,也就是说没有按照从0开始到999。

都说synchronized可以实现同步方法或同步块,这里怎么就不行呢?

 

先从同步的机制来分析一下,同步是通过锁来实现的,那么上面的例子中,锁定了什么对象,或锁定了什么类呢?里面有两个变量,一个是i,一个是threadnum;i是方法内部的,threadnum是私有的。

再来了解一下synchronized的运行机制:

      在java程序中,当使用synchronized块或synchronized方法时,标志这个区域进行监视;而JVM在处理程序时,当有程序进入监视区域时,就会自动锁上对象或类。

 

那么上面的例子中,synchronized关键字用上后,锁定的是什么呢?

当synchronized方法时,锁定调用方法的实例对象本身做为对象锁。本例中,10个线程都有自己创建的TestThread的类对象,所以获取的对象锁,也是自己的对象锁,与其它线程没有任何关系。

 

要实现方法锁定,必须锁定有共享的对象。

 

对上面的实例修改一下,再看看:

package thread_test;

/**
 * 测试扩展Thread类实现的多线程程序 
 * 
 * @author ciding 
 * @createTime Dec 7, 2011 9:37:25 AM
 *
 */
public class TestThread extends Thread{ 
	private int threadnum;
	private String flag;	//标记
	
	public TestThread(int threadnum,String flag) { 
       		 this.threadnum = threadnum; 
        		this.flag = flag;
    	}
	
	@Override
    	public void run() { 
		synchronized(flag){
			for(int i = 0;i<1000;i++){ 
	            			System.out.println("NO." + threadnum + ":" + i );
	        		} 
		}
    	} 

    	public static void main(String[] args) throws Exception { 
    		String flag = new String("flag");
    		for(int i=0; i<10; i++){
        			new TestThread(i,flag).start();
        			Thread.sleep(1);
    		}
    	} 
}

 

也就加了一个共享的标志flag。然后在通过synchronized块,对flag标志进行同步;这就满足了锁定共享对象的条件。

是的,运行结果,已经按顺序来了。

 

 

一下写的太多,先休息一下,下一节再补上synchronized的使用下

 多线程——同步(synchronized)下

 

 

 

 Java多线程及线程池专题 汇总

 http://ciding.iteye.com/blog/1300110

  

多线程——同步(synchronized)上

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
1、问题的引出 class MyThread implements Runnable{ private int ticket = 5 ; // 假设一共有5张票
0.需求 需求是这样的:实现多线程拨号,从数据中的批量读取需要拨打的号码,然后多线程拨号。拨号就
synchronized同步块实例 在java中,每个对象都包含了一把锁(也叫做“监视器”),它自动成为对象的
转自:http://blog.csdn.net/chen77716/article/details/6618779 目前在Java中存在两种锁机制:sync
synchronized同步块实例 在java中,每个对象都包含了一把锁(也叫做“监视器”),它自动成为对象的
首先来看下一个场景,某电影院某个时间4个窗口同时在卖票,本场电影总共票只有100张,卖完为止。看
本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希望通过本
本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希望通过本
本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希望通过本
转自 http://www.cnblogs.com/freshman0216/archive/2008/07/27/1252253.html 本篇从Monitor,Mutex
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号