码迷,mamicode.com
首页 > 编程语言 > 详细

java中synchronize锁 volatile thread.join()方法的使用

时间:2015-03-11 23:12:53      阅读:947      评论:0      收藏:0      [点我收藏+]

标签:

对于并发工作,你永远不知道一个线程何时运行,你需要某种方式来避免两个任务访问相同的资源,即要避免资源竞争,至少在关键代码上不能出现这样的情况,否则多个线程同时对某个内存区域操作会导致数据破坏。

程序代码中的临界区是需要互斥访问的,同一时刻只能有一个线程来访问临界区,也就是线程对临界区的访问时互斥的。

竞争条件:当多个线程同时访问某个共享的内存区域并且对其进行读写操作时,就会出现数据破坏。这就是竞争条件。避免竞争条件的方法是synchronized加锁。

样例,设有一个现成,该线程的任务是对共享变量count值+1。设count值的初始值为0,开辟1000个相同的线程,那么线程执行完后,count的值应该为1000(因为每个线程中都对count做了加一操作),但是实际效果会出现错误,这是因为出现了竞争条件。

解决办法:使用synchronized锁,

先定义一个object对象:

private final static Object lockObj = new Object();

下面即是同步块,在同步块中进行关键操作。

					synchronized(lockObj)
					{
						syn.count = syn.count+1;	
						temp = temp+1;
					}

  

-------------------------------------------------------------------------------

下面是正题

JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。假如再细的分类,synchronized可作用于instance变量、object reference(对象引用,例如this)、static函数和class literals(类名称字面常量)身上。下面讨论synchronized用到不同地方对代码产生的影响:
假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都能够调用他们。
1.把synchronized当作函数修饰符时,示例代码如下:
public synchronized void method(){
//….
}
这也就是同步方法,那这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。上边的示例代码等同于如下代码:
public void method()
{
synchronized (this) // (1)
{
//…..
}
}
(1)处的this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见,同步方法实质是将synchronized作用于Object Reference。那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱。
2.同步块,示例代码如下:
public void method(SomeObject so) {
synchronized(so)
{
//…..
}
}
这时,锁就是so这个对象,谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(它得是个对象)来充当锁:
class Foo implements Runnable
{
private byte[] lock = new byte[0]; // 特别的instance变量
Public void method()
{
synchronized(lock) { //… }
}
//…..
}
注:零长度的byte数组对象创建起来将比任何对象都经济。查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。
3.将synchronized作用于static 函数,示例代码如下:
Class Foo
{
public synchronized static void method1() // 同步的static 函数
{
//….
}
public void method2()
{
synchronized(Foo.class) // class literal(类名称字面常量)
}
}
代码中的method2()方法是把class literal作为锁的情况,他和同步的static函数产生的效果是相同的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class类,而不再是由这个Class产生的某个具体对象了)。

转载请注明:struts教程网 » synchronized的深刻认识

 

 

如何来定义共享变量:

1、在主类中定义一个final变量,让其在其他线程中也可以执行。

2、使用static定义线程公用的成员变量,在一个类实现runnable接口,其中定义一个static变量,这个变量就为所有使用此接口的类对象所共用,即所有的类对象共用一份这个变量的拷贝。

 

1、java中synchronize可以用来给对象、代码块等加锁。synchronize关键字可以出现在函数外,也可以出现在函数体

2、没有volatile就没有java多线程

3、Thread.join()可以设置让当前线程执行完毕后再执行其他线程,这在控制线程的执行顺序上很有用。

下面通过一个代码来描述java多线程中可能出现的资源竞争条件(race condition)问题。

 

java中synchronize锁 volatile thread.join()方法的使用

标签:

原文地址:http://www.cnblogs.com/wll-zju/p/4331092.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!