`
xumingrencai
  • 浏览: 1181052 次
文章分类
社区版块
存档分类
最新评论

Synchronize与JAVA内存模型

 
阅读更多

synchronized 来控制安全性, synchronized synchronized 方法 和synchronized 快,使用synchronized 块时, 一定要显示的获得该对象的锁(如synchronized object))而方法则不需要。

  JAVA 的内存模型是对每一个进程有一个主内存, 每个线程有自己的内存, 他们从主内存中取数据,然后计算, 再存入主内存中。

  并发问题如下:如果多个线程同事操作同一数据, A线程从主内存中取的I的值为1, 然后进行加1操作,这时B线程也取I的值, 进行加2操作, 然后A存入2到主内存中, B也存入, 这样就覆盖了A的值(同数据库中的并发问题一样)。

  解决办法是用synchronized , 如用synchronizedI)。被synchronized 修饰的方法(块)把以下三步操作当成一个原子操作:取数据, 操作数据, 存数据。 我们知道原子操作是不可以被打断的, 所以其保证了数据一致性,这样同一时间只有一个线程再执行, 对性能有一定的影响。这也是synchronized 的第二个作用:保证同一时间只有一个线程在运行。当实现SOCKET连接的时候经常用到.

  JAVA中规定对非FLOAT, LONG的原始类型的取和存操作为原子操作。其实就是对一个字(32位)的取,存位原始操作, 因为FLOAT, LONG为两个字节的长度,所以其取, 存为非原子操作。 如果想把他们也变为原子操作, 可以用VOLATILE关键字来修饰.

synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
1. synchronized
方法
:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:
public synchronized void accessVal(int newVal);
synchronized
方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。
synchronized
方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 synchronized 块。
2. synchronized
块:通过 synchronized关键字来声明synchronized 块。语法如下:
synchronized(syncObject) {
//
允许访问控制的代码
}
  synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。
notify()
notifyAll()Object的方法,Objectwait()方法配合使用,而且这三个方法必须在同步块中调用.
如下:
在线程1中执行如下代码
...
synchronized(obj1) //1.
进入同步块
{
try {
...
obj1.wait(); //2.
进入暂停状态
}catch (InterruptedException exp) {}
}
1.
当前同步对象(monitor)obj1,obj1是任一实例,若是同步方法,则同步对象是this.进入同步块后,obj1为锁定状态,锁定状态对obj1本身无任何影响,而其它线程执行到同一代码时,因不能获得锁,处于Block状态,一旦解锁,block的线程自动继续执行.
2.
调用obj1.wait()有两个作用,一是使线程进入等待状态,二是解锁obj1,这时被block的线程将获得锁.线程1要退出等待必须要由其它线程显式的调用obj1.notify()notifyAll()方法.

...
synchronized(obj1)
{
...
obj1.notify(); //3.
wait的线程发通知信息
...
}
...
若其它线程执行到此时,线程1处于wait状态,wait状态解除,解除后,若线程1若得到锁就能继续执行,若有多个线程处于obj1wait状态,notify将随机选一个线程激活,notifyAll是同时解除所有的wait状态.
notifyAll()
让等待某个对象K的所有线程离开阻塞状态,
notify()
随机地选取等待某个对象K的线程,让它离开阻塞状态。
notify(),notifyAll()
非常有用,在一个synchronized(lockObj)块中当调用lockObj.wait()时,线程就已经将锁放开来了,这时当另外一个线程调用lockObj.notify()时,等待的线程就会继续执行下去了。这是一种非常高效的线程同步机制。如果没有他,用sleep()来同步的话就太浪费时间了。
一个简单的例子:
thread1 receive data
thread2 pase received data
lockObj
buf
buf中没有数据时,thread2中调用buf.wait释放锁,让thread1有机会执行。
thread1收到数据时,调用buf.notify()通知thread1去处理收到的数据。
如果在同步块入口点阻塞,不须其它线程调用notify(),调了也没效果,同步块能自动获得锁
如果是wait造成了阻塞,须用notfiy()激活,这两个方法是配合使用
notify
notifyAllwait :
主要是为了解决持有监视器钥匙的线程暂停等待另一线程完成时可能发生死锁的问题。wait()方法使调用线程等待,直到发生超时或另一线程调用同一对象的notify()或notifyAll()方法。wait() 方法的用法如下:wait()wait(long timeoutPeriodInMilliseconds)前者等待被通知,后者等待超时或通知。线程调用wait()方法时,释放所持有的钥匙让另一等待线程进入监视区。notify()方法只唤醒一个等待线程,而notifyAll()唤醒所有等待该监视器的线程。注意,这些方法只能在监视区内调用。否则会输出一种RuntimeException类型的IllegaMonitorStateException异常状态。
够详细清楚的吧。
总之wait()让线程等待,notify()notifyall()激活某个等待线程,其实就是撤销该线程的中断状态,从而使他们有机会再次运行
有时会遇到如下问题,程序的一部分在写数据,另一部分读数据,但有时会出现读部分超前写部分,
这就是典型的产生者/消耗者问题.
.wait:
是一个线程睡眠,直到在相同的对象上调用notifynotifyAll
.notify:
启动第一个在相同对象调用wait的线程
.notifyAll:
启动在相同的对象调用wait的所有线程

分享到:
评论

相关推荐

    java synchronize 线程同步

    当多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。

    Java线程/内存模型的缺陷和增强

     一、Java内存模型 在了解Java的同步秘密之前,先来看看JMM(JavaMemoryModel)。 Java被设计为跨平台的语言,在内存管理上,显然也要有一个统一的模型。而且Java语言最大的特点就是废除了指针,把

    Java 中synchronize函数的实例详解

    主要介绍了Java 中synchronize函数的实例详解的相关资料,希望通过本文能帮助到大家理解使用synchronize函数的使用方法,需要的朋友可以参考下

    delphi vcl线程同步synchronize

    delphi vcl线程同步synchronize

    Java synchronize线程安全测试

    主要介绍了Java synchronize线程安全测试,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    CALL RFC synchronize and asychronize Examples

    CALL RFC synchronize and asychronize Examples

    Synchronize It 3.5文件夹同步器 简体中文界面

    Synchronize It!还有其他特点如下: 1.可以自订许多的项目,包括过滤器、专案、颜色等等。 2.可以进行多种同步任务独立保存和点用,也可组合多个任务一次同步搞定。 3.支持压缩文件的同步。 4.内建二进位文件的比较...

    Java synchronize底层实现原理及优化

    主要介绍了Java synchronize底层实现原理及优化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java之Synchronize学习

    Synchronize的几种实现 Synchronize有三种实现。 同步方法,修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁 静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁 修饰代码块...

    Java对象锁和类锁全面解析(多线程synchronize

    Java对象锁和类锁全面解析(多线程synchronized关键字)编程开发技术共14页.pdf.zip

    JAVA面试题最全集

    IS09000和CMM(软件能力成熟度模型)认证是国际上通用的软件质量评估方法.CMM的五个成熟度等级。 第一,谈谈final, finally, finalize的区别。 final?修饰符(关键字)如果一个类被声明为final,意味着它不能再...

    synchronize底层实现原理

    synchronize底层实现原理 Java文件想要看字节码通常使用 javap 命令将java的class文件反汇编,具体操作步骤如下: 1. 先写好一个SynchronizedTest.java文件(下面贴出) 2. 在java文件的目录下,使用命令 javac ...

    java 面试题 总结

    内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的...

    FTP_synchronize_0_9_6_1_dll

    NotePad++的ftp插件,注意是32位的,涵盖FTP_synchronize.dll、FTP_synchronizeA.dll

    Blender批量网格模型加效果器插件 Synchronize Modifiers V2.2.0.zip

    Synced Modifiers 是一个 Blender 插件,允许您同时向多个对象添加修改器,并使用驱动程序自动同步所有修改器。 如果你想要免费的blender插件、模型等可以看看这个blender资源库:...还有免费的Blender入门教程:...

    Java 7 Concurrency Cookbook

    of how to use the new Java 7 Phaser class to synchronize tasks divided into phases. Chapter 4, Thread Executors will teach the readers to delegate the thread management to executors. They allow ...

    synchronize.pdf

    synchronize详解

    synchronize.zip

    synchronize.zip

    vnc.rar_Computers_file synchronize

    simple configure file to synchronize the connection between two computers (using vnc)

Global site tag (gtag.js) - Google Analytics