- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章java多线程编程之Synchronized关键字详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点.
所谓对象锁,就是就是synchronized 给某个对象 加锁。关于 对象锁 可参考:这篇文章 。
1、分析 。
synchronized可以修饰实例方法,如下形式:
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的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在 java 中不使用“同步”关键字的情况下,是否有其他方法可以同步类或方法? 谢谢, 马利卡琼·科卡塔努尔 最佳答案 您可能想查看并发包中引入的对 JDK 5 的更改。 http://java.su
第 1 部分: 假设下面这段代码 void method1(){ synchronized (lockObject){ method2(); System.ou
我有一个 REST 服务器和一个在移动设备上运行的客户端应用程序。客户端有一些数据并希望从服务器获取数据更新。如何以 RESTful 方式在单个事务中执行此操作? 假设客户有以下元素: widge
我有一个多线程 Java 应用程序。在一种方法中,需要同步一个 ArrayList。由于 arrayList 不是线程安全的,所以我必须使用同步。问题是 ArrayList 类型的对象不是对象的成员变
我正在阅读 Android 示例中的 BluetoothChatService.java 文件,有一件事特别让我感到困惑。 方法在多个位置访问静态成员,并且定义为同步。 在另一部分中,正在访问同一个静
我知道为了实现线程安全和同步,我们使用同步块(synchronized block)或方法。 但我无法理解声明- “Java 中的同步块(synchronized block)在某些对象上同步 ” 任
在 Scala 中使用 JDBC 的示例中,有以下代码: this.synchronized { if (!driverLoaded) loadDriver() } 为什么this.synchro
abstract class A { protected abstract int isRunning(); public void concreteMethod() { synchr
有谁可以分享一下他们的经验吗?“我们什么时候在同步方法和同步块(synchronized block)之间进行调用”有任何性能问题吗? 最佳答案 When do we make a call to u
这是我之前问题的后续问题,Is this variable being safely accessed by using synchronization? 对于下面的程序, Class SubClas
我目前正在为 N 体问题实现多线程版本的 Barnes-Hut 算法。虽然该算法有效,但它不是很优化,我正在尝试减少我的程序的运行时间。 我已经确保有多个线程可以准确地找到我正在使用的空间的边界,并意
我有这门课: public class MyClass { public MyClass(){} public void actionA(){ synchronized
又是一个关于ArrayList和synchronize的问题。 我只想知道这段代码到底做了什么: ArrayList list = ....; synchronized (list) { if
我可以在另一个同步块(synchronized block)中包含同步块(synchronized block)以同步另一个对象吗? 例子: synchronized(myObjetc1){
public class ObjectCounter { private static long numOfInstances = 0; public ObjectCounter(){
我在某处读到,对于 various reasons 应该避免 synchronized(this) .然而,我遇到的一些值得尊敬的代码在构造函数中使用了以下内容: public SomeClass(C
Java 为同步代码的关键部分提供了一种非常方便的习惯用法: synchronized(someObject) { // do something really important all b
我有一个 WeakReference 的 Collections.synchronizedList,_components; 我写了类似下面的内容,希望编译者会提示: public boolean a
使用下面两个版本的Singleton Classes有什么区别 首先我使用的是synchronized(Singleton.class) 在第二个我使用同步(Obj)//第一种类型 公共(public
我正在查看 DatagramSocket 的源代码,我发现了这个: public void disconnect() { synchronized (this) { if (i
我是一名优秀的程序员,十分优秀!