Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 420|回复: 0

开发交流:java的同步机制二

[复制链接]

该用户从未签到

发表于 2011-10-24 10:14:36 | 显示全部楼层 |阅读模式
       每个Object都会有1个锁.
  同步就是串行使用一些资源.
  (说明:以下有些例子为了突出重点,省略了不必要的代码.特别是省掉了一些成员变量,就是需要同步的对象.)

  1. 多线程中对共享、可变的数据进行同步.
  对于函数中的局部变量没必要进行同步.
  对于不可变数据,也没必要进行同步.
  多线程中访问共享可变数据才有必要.

  2. 单个线程中可以使用synchronized,而且可以嵌套,但无意义.
      
class Test {

  public static void main(String[] args) {

  Test t = new Test();

  synchronized(t) {

  synchronized(t) {

  System.out.println("ok!");

  }

  }

  }

  }
复制代码

  

  3. 对象实例的锁
  
class Test{

  public synchronized void f1(){

  //do something here

  }

  public void f2(){

  synchronized(this){

  //do something here

  }

  }

  }
复制代码


  上面的f1()和f2()效果一致, synchronized取得的锁都是Test某个实列(this)的锁.
  比如: Test t = new Test();
  线程A调用t.f2()时, 线程B无法进入t.f1(),直到t.f2()结束.
  作用: 多线程中访问Test的同一个实例的同步方法时会进行同步.
  
      4. class的锁
  
class Test{

  final static Object o= new Object();

  public static synchronized void f1(){

  //do something here

  }

  public static void f2(){

  synchronized(Test.class){

  //do something here

  }

  }





public static void f3(){

  try {

  synchronized (Class.forName("Test")) {

  //do something here

  }

  }

  catch (ClassNotFoundException ex) {

  }

  }

  public static void g(){

  synchronized(o){

  //do something here

  }

  }

  }
复制代码


  上面f1(),f2(),f3(),g()效果一致
  f1(),f2(),f3()中synchronized取得的锁都是Test.class的锁.
  g()是自己产生一个对象o,利用o的锁做同步
  作用: 多线程中访问此类或此类任一个实例的同步方法时都会同步. singleton模式lazily initializing属于此类.

  5. static method
        
class Test{

  private static int v = 0;

  public static void f1(){

  //do something, 但函数中没用用到v

  }

  public synchronized static void f2(){

  //do something, 函数中对v进行了读/写.

  }

  }
复制代码
  
  多线程中使用Test的某个实列时,
  (1) f1()是线程安全的,不需要同步
  (2) f2()这个静态方法中使用了函数外静态变量,所以需要同步.

  6. 对线程的run()进行同步没有意义,如 public synchronized void run()
      
class Test extends Thread{

  public synchronized void run(){

  while(true){

  //do something

  }

  }

  public synchronized void f(){

  //...

  }

  }
复制代码
  
  这种例子会有一个问题, 执行run()时(内部在循环), 外部无法执行f()
  class Test extends Thread{
  public synchronized void run(){
  //do something
  }
  }
  这种例子同步基本没用, 因为run()通常靠 new Test().start()来执行的.
  因为Test实例不同,锁也不同。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-11 03:02 , Processed in 0.352695 second(s), 34 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表