gpt4 book ai didi

java多线程编程之Synchronized关键字详解

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 25 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章java多线程编程之Synchronized关键字详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点.

所谓对象锁,就是就是synchronized 给某个对象 加锁。关于 对象锁 可参考:这篇文章 。

 1、分析 。

synchronized可以修饰实例方法,如下形式:

java" id="highlighter_320519">
?
1
2
3
4
public class MyObject {
   synchronized public void methodA() {
     //do something....
   }

这里,synchronized 关键字锁住的是当前对象。这也是称为对象锁的原因.

为啥锁住当前对象?因为 methodA()是个实例方法,要想执行methodA(),需要以 对象.方法() 的形式进行调用(obj.methodA(),obj是MyObject类的一个对象,synchronized就是把obj这个对象加锁了).

上面代码也可写成这样:

?
1
2
3
4
5
6
7
8
public class MyObject {
 
   public void methodA() {
     synchronized ( this ){
       //do something....
     }
   }

2、特点 。

使用synchronized关键字同步一个明显的特点是:MyObject类中定义有多个synchronized修饰的实例方法时,若多个线程拥有同一个MyObject类的对象,则这些方法只能以同步的方式执行。即,执行完一个synchronized修饰的方法后,才能执行另一个synchronized修饰的方法.

如下:

?
1
2
3
4
5
6
7
8
9
10
public class MyObject {
 
   synchronized public void methodA() {
     //do something....
   }
 
   synchronized public void methodB() {
     //do some other thing
   }
}

MyObject类中有两个synchronized修饰的方法.

?
1
2
3
4
5
6
7
8
9
10
public class ThreadA extends Thread {
 
   private MyObject object;
//省略构造方法
   @Override
   public void run() {
     super .run();
     object.methodA();
   }
}

线程A执行methodA() 。

?
1
2
3
4
5
6
7
8
9
10
public class ThreadB extends Thread {
 
   private MyObject object;
//省略构造方法
   @Override
   public void run() {
     super .run();
     object.methodB();
   }
}

线程B执行methodB() 。

?
1
2
3
4
5
6
7
8
9
10
11
public class Run {
   public static void main(String[] args) {
     MyObject object = new MyObject();
 
     //线程A与线程B 持有的是同一个对象:object
     ThreadA a = new ThreadA(object);
     ThreadB b = new ThreadB(object);
     a.start();
     b.start();
   }
}

由于线程A和线程B持有同一个MyObject类的对象object,尽管这两个线程需要调用不同的方法,但是必须是同步的,比如:线程B需要等待线程A执行完了methodA()方法之后,它才能执行methodB()方法.

 3、结论 。

从上可以看出,本文中讲述的 synchronized 锁的范围是整个对象。如果一个类中有多个synchronized修饰的同步方法,且多个线程持有该类的同一个对象(该类的相同的对象),尽管它们调用不同的方法,各个方法的执行也是同步的.

如果各个同步的方法之间没有共享变量,或者说各个方法之间没有联系,但也只能同步执行,这会影响效率.

4、应用--使用synchronized避免 因数据不一致性而导致读脏数据的情况 。

如下示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyObject {
 
   private String userName = "b" ;
   private String passWord = "bb" ;
  
   synchronized public void methodA(String userName, String passWord) {
     this .userName = userName;
     try {
       Thread.sleep( 5000 );
     } catch (InterruptedException e){
      
     }
     this .passWord = passWord;
   }
 
   synchronized public void methodB() {
     System.out.println( "userName" + userName + ": " + "passWord" + passWord);
   }
}

methodA()负责更改用户名和密码。在现实中,一个用户名对应着一个密码.

methodB()负责读取用户名和密码.

如果methodB()没有用synchronized 修饰,线程A在调用methodA()执行到第7行,更改了用户名,因某种原因(比如在第9行睡眠了)放弃了CPU.

此时,如果线程B去执行methodB(),那么读取到的用户名是线程A更改了的用户名("a"),但是密码却是原来的密码("bb")。因为,线程A睡眠了,还没有来得及更改密码.

但是,如果methodB()用synchronized修饰,那么线程B只能等待线程A执行完毕之后(即改了用户名,也改了密码),才能执行methodB读取用户名和密码。因此,就避免了数据的不一致性而导致的脏读问题.

以上就是本文的全部内容,希望对大家学习java程序设计有所帮助.

最后此篇关于java多线程编程之Synchronized关键字详解的文章就讲到这里了,如果你想了解更多关于java多线程编程之Synchronized关键字详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com