读书人

java多线程深入体味及分析

发布时间: 2012-09-10 22:20:13 作者: rapoo

java多线程深入体会及分析

对于java中多线程并发问题之前理解一直不到位,最近在使用synchronized关键字时发现了很多使用误区。

解析1:分析以下代码

class? Info{

????? public synchronized add(){

?????????????? System.out.println("add");

????? }
????? public synchronized delete(){

?????????????? System.out.println("delete");

????? }

}

从以上代码可以得知同一对象的add和delete方法都不允许同时被2个线程访问,从这个角度理解是没有问题的。

我们再对上面代码进行改造,让其变成一单例类

解析2:分析以下代码

class? Info{

????? private static Info? Info1=null;

????? private Info(){}???????????????????? //私有构造器

????? //获得单例统一如口

????? public synchronized static Info getInstance(){

?????????????? if(info1==null)

????????????????? info1=new Info();

?????????????? return info1;

????? }
????? public synchronized add(){

?????????????? System.out.println("add");

????? }
????? public synchronized delete(){

?????????????? System.out.println("delete");

????? }

}

以上代码在整个jvm运行过程中只存在一个实例,如果此时线程A正在访问方法add(),那么其它线程均不可访问该类的任何带有synchronized 关键字的方法,因为synchronized关键会对当前实例加锁,即每个java实例都会有一把实例锁,当线程A访问add()方法时即对该实例加了一把锁,当其它线程访问带有synchronized关键字的方法delete()时jvm会先检察当前对象是否被加锁,如果已加锁则会被阻塞。



解析3:分析以下代码

class? Info{

????? public static? synchronized add(){

?????????????? System.out.println("add");

????? }
????? public static synchronized delete(){

?????????????? System.out.println("delete");

????? }
????? public static? void edit(){

?????????????? System.out.println("delete");

????? }
???? public synchronized void view(){

?????????????? System.out.println("delete");

????? }

}

我们现在开始分析一种特殊形式的同步过程

假如线程A正在访问add()方法,那么其它线程均无法访问delete方法,但edit()、view()方法是可以访问的,因为在静态方法上使用synchronized关键字表示对类进行加锁,当其它线程访问该类带有synchronized关键字的方法时,jvm都会判断该类是否被加锁,如果被加锁则会被阻塞。但是未加synchronized关键字的方法是可以被执行,并且view()方法虽然加了synchronized但由于是属于Info类的,所以也不会被锁。



总结以上内容

Synchronized是java语言级别内置的同步机制,不同与java中的Semaphore,Mutex。Synchronized的背后机制是Java在语言级上的锁机制:

类锁:对于每一个类,自动配套一个类锁,该锁临界量为1
实例锁:对于每一个类实例化后的一个对象,自动配套一个对象锁,该锁临界量为1
对于类锁,目前注意到,只能应用到类得某个方法上:

静态方法锁:static synchronized method();
对于实例锁,有以下几种方式:

非静态方法锁:synchronized method();
代码块锁:synchronized{ }或synchronized(this){ }
指定类实例锁:synchronized(Object ob){ }
非静态方法锁与代码块锁实质都一样,是对当前所属类得实例加锁。而指定类实例锁,是对括号里的对象ob加锁,这一点很有意思,灵活运用指定类锁可以构建一些稍微负责的并行程序模型。

其中类锁与实例锁各自独立,不相互冲突,一个synchronized 指定锁,要么是类锁,要么是实例锁,是互斥的


最后一点是synchronized关键词不能被直接继承,子类在继承负责,覆盖父类的synchronized方法时候,必须同样显示用synchronized关键词。而子类如果不覆盖父类synchronized关键词的非静态方法,直接继承并使用父类的非静态方法时,父类的synchronized字段在子类对象仍然是有效的。

好吧,总结就到此为至,分析的不是太深入,希望这篇文章能启发大家的思想。

如果有不同建议的同学可以给我留言!

?

1 楼 a12053094 2012-03-03 add方法等没有返回参数,编译不通过

读书人网 >编程

热点推荐