synchronized关键字,需要编写多线程代码的java开发者经常会用到的关键字,它的主要作用是使方法同步,本文将通过一系列测试,希望可以深入解此关键字.
一.synchronized的使用方法.
开始之前,先要搞清楚synchronized字段的使用方法
1.synchronized可以用来声明成员方法,
public synchronized int method () {
}
2.synchronized可以用在代码块中,例如
public void method {
synchronized(this) {
dosth();
}
}
注,括号里必须是一个实例
二.synchronized的作用
下面将开始具体的测试,这次主要测试将synchronized用于声明方法时的主要作用.下面的TestBean.java,这是用户测试的主体类,测试将围绕此类逐步进行.
package org.sluggard.bolg.synctest;
/**
* 此类为测试的主体类,其中声明了2个动态的同步方法,
* 2个静态的同步方法,1个动态的非同步方法和1个静态的非同步方法,所有命名为A的方法,
* 进入方法后会sleep10秒,所有B方法,将只sleep1秒,而所有的非同步方法,将sleep5秒.
* @author Frank
*
*/
public class TestBean {
private String dynamicField;
private static String staticField;
/**
* 动态的同步方法A
* @param value
*/
public synchronized void dynamicSyncMethodA(String value) {
System.out.println("I'm synchronized methodA");
SleepUtil.sleep(10);
dynamicField = value;
System.out.println("Now field is : " + dynamicField);
}
/**
* 动态的同步方法B
*/
public synchronized void dynamicSyncMethodB(String value) {
System.out.println("I'm synchronized methodB");
SleepUtil.sleep(1);
dynamicField = value;
System.out.println("Now field is : " + dynamicField);
}
/**
* 静态同步方法A
*/
public static synchronized void staticSyncMethodA(String value) {
System.out.println("I'm static synchronized methodA");
SleepUtil.sleep(10);
staticField = value;
System.out.println("Now field is : " + staticField);
}
/**
* 静态同步方法B
*/
public static synchronized void staticSyncMethodB(String value) {
System.out.println("I'm static synchronized methodB");
SleepUtil.sleep(1);
staticField = value;
System.out.println("Now field is : " + staticField);
}
/**
* 动态非同步方法
*/
public void dynamicUnsyncMethod(String value) {
System.out.println("I'm dynamic unsynchronized method");
SleepUtil.sleep(5);
dynamicField = value;
System.out.println("Now field is : " + dynamicField);
}
/**
* 静态非同步方法
*/
public static void staticUnsyncMethod(String value) {
System.out.println("I'm static unsynchronized method");
SleepUtil.sleep(5);
staticField = value;
System.out.println("Now field is : " + staticField);
}
}
abstract class SleepUtil {
public static void sleep(int i){
try {
Thread.sleep(i*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
下面将针对此类编写测试代码,我们将解决一下一系列问题.
1,synchronized会所住整个类吗?
Test.java,我们为动态方法A和动态方法B分别编写了2个线程类,并分别对2个执行2个实例的synchronized方法.
package org.sluggard.bolg.synctest;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
TestBean testBean1 = new TestBean();
TestBean testBean2 = new TestBean();
ThreadDSA dsa = new ThreadDSA(testBean1);
ThreadDSB dsb = new ThreadDSB(testBean2);
dsa.start();
SleepUtil.sleep(1);
dsb.start();
}
}
class ThreadDSA extends Thread{
@Override
public void run() {
testBean.dynamicSyncMethodA("DSA");
}
private TestBean testBean;
public ThreadDSA(TestBean testBean) {
super();
this.testBean = testBean;
}
}
class ThreadDSB extends Thread{
@Override
public void run() {
testBean.dynamicSyncMethodB("DSB");
}
private TestBean testBean;
public ThreadDSB(TestBean testBean) {
super();
this.testBean = testBean;
}
}
执行结果如下
引用
I'm synchronized methodA
I'm synchronized methodB
Now field is : DSB
Now field is : DSA
然后,我们将main方法进行修改,改成下面的样子
public static void main(String[] args) {
TestBean testBean = new TestBean();
ThreadDSA dsa = new ThreadDSA(testBean);
ThreadDSB dsb = new ThreadDSB(testBean);
dsa.start();
SleepUtil.sleep(1);
dsb.start();
}
执行结果如下
引用
I'm synchronized methodA
Now field is : DSA
I'm synchronized methodB
Now field is : DSB
答案:synchronized并没有锁住整个类,而是仅仅锁住了某个实例,不同实例中的动态同步方法是不会同步的.
2.当程序进入synchronized方法后,非同步方法可以执行吗?
我们在Test.java中为非同步方法加入一个线程类
class ThreadDUS extends Thread{
@Override
public void run() {
testBean.dynamicUnsyncMethod("DUS");
}
private TestBean testBean;
public ThreadDUS(TestBean testBean) {
super();
this.testBean = testBean;
}
}
对main方法进行修改
public static void main(String[] args) {
TestBean testBean = new TestBean();
ThreadDSA dsa = new ThreadDSA(testBean);
ThreadDUS dus = new ThreadDUS(testBean);
dsa.start();
SleepUtil.sleep(1);
dus.start();
}
执行结果如下
引用
I'm synchronized methodA
I'm dynamic unsynchronized method
Now field is : DUS
Now field is : DSA
答案:同步锁不会所住非同步的方法,如果你希望2个方法顺序执行,就必须对他们的都枷锁.
3.synchronized会同时锁住动态方法和静态方法吗?
首先,我们先修改一下TestBean,在动态方法中加入对静态成员变量的操作
public synchronized void dynamicSyncMethodA(String value) {
System.out.println("I'm synchronized methodA");
SleepUtil.sleep(10);
dynamicField = value;
staticField = value;
System.out.println("Now dynamicfield is : " + dynamicField + "\nNow staticfield is : " + value);
}
同样,我们为静态同步方法加入线程类,
class ThreadSSA extends Thread{
@Override
public void run() {
TestBean.staticSyncMethodA("SSA");
}
}
class ThreadSSB extends Thread{
@Override
public void run() {
TestBean.staticSyncMethodB("SSB");
}
}
然后修改main方法
public static void main(String[] args) {
TestBean testBean = new TestBean();
ThreadDSA dsa = new ThreadDSA(testBean);
ThreadSSB ssb = new ThreadSSB();
ThreadSSA ssa = new ThreadSSA();
dsa.start();
SleepUtil.sleep(1);
ssb.start();
ssa.start();
}
执行结果如下
引用
I'm static synchronized methodB
Now field is : SSB
I'm static synchronized methodA
Now dynamicfield is : DSA
Now staticfield is : DSA
Now field is : SSA
答案:静态方法和动态方法的锁是不同的,动态方法只与动态方法同步,静态方法只与静态方法同步.
三,总结,在动态方法声明中加入synchronized字段,方法将会在运行时获得此对象实例的锁,此实例的所有synchronized方法在锁为释放前将不无法执行,但是其他实例,此实例的非同步方法和静态方法将不受影响.一个类的所有静态方法共享同一把锁.
这是本系列文章的第一篇,主要说明在同一个类中,在声明方法时加入synchronized关键字的作用,以后的文章中,会对synchronized的其他用法,以及多个类之间synchronized关键字的作用进行测试.
分享到:
相关推荐
Java 锁机制 Synchronized 是 Java 语言中的一种同步机制,用于解决多线程并发访问共享资源时可能出现的一些问题。 Java 锁机制 Synchronized 的概念 在 Java 中,每个对象都可以被看作是一个大房子,其中有多个...
方法锁是`synchronized`关键字应用于方法的一种形式,它既可以是类锁(用于静态方法),也可以是对象锁(用于非静态方法)。上面的类锁和对象锁示例中,`method()`就是方法锁的体现。 **非公平锁** 在Java中,`...
在Java高并发编程领域,理解Synchronized锁的升级机制是非常重要的。 首先需要知道的是,Synchronized锁在JVM中实现了从低到高的不同锁级别,包括无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。锁的升级并不...
在Objective-C中,当你使用`@synchronized`块包围一段代码时,会为指定的对象创建一个互斥锁。如果当前线程已经持有了该锁,那么它可以再次获取并执行内部的代码,而不会造成死锁。这种特性使得在嵌套使用`@...
标题中的"java 多线程synchronized互斥锁demo"指的是一个示例,展示了如何在多线程环境下使用`synchronized`关键字创建互斥锁,确保同一时间只有一个线程可以访问特定的代码块或方法。 描述中的"一个多线程访问的同...
Java中的`synchronized`关键字是实现线程安全的关键机制,它基于Java对象头的Mark Word进行锁的状态管理。Mark Word是一个动态变化的数据结构,用于存储对象的HashCode、分代年龄、锁状态标志等信息。在32位JVM中,...
《深入理解synchronized锁自旋机制》 在Java并发编程中,`synchronized`关键字扮演着重要的角色,它提供了一种线程同步机制,确保共享资源在同一时刻只能被一个线程访问。本文将深入探讨`synchronized`锁的内部机制...
Synchronized 是一种实例锁,它锁定的是当前对象的实例。也就是说,Synchronized 关键字所修饰的方法或代码块只能被当前对象的实例锁定。这种锁定机制可以防止多个线程同时访问该对象的同一个 synchronized 块。 ...
Lock是显式锁,需要手动的开启和关闭,synchronized锁是隐式锁,只要出了作用域就会自动释放。Lock只有代码块锁,synchronized既有代码块锁还有方法锁。 使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。有...
Java synchronized同步锁可以保证同一时刻只有一个线程操作同一资源,使用wait()、notify()切换线程状态保证线程操作的前后顺序实现线程交互。 Java线程状态有五种:新建状态、就绪状态、运行状态、休眠状态和死亡...
* 若此对象对应的类中包含了多个 synchronized 修饰的方法或代码块,多个线程访问同一个对象的任意 synchronized 修饰的方法或代码块,只要有一个线程拥有了 synchronized 同步锁,其他线程不管想访问 synchronized ...
《深入剖析synchronized锁原理——从Java对象头的角度》 synchronized关键字在Java中扮演着重要的角色,它是Java实现同步的基础,确保了多线程环境下的数据一致性。不同于基于JDK实现的Lock接口(如ReentrantLock)...
Synchronized 关键字的作用是取得对象的锁,而不是把一段代码或函数当作锁。每个对象只有一个锁与之相关联。实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。 当 ...
本文将深入探讨Synchronized关键字锁和ReentrantLock锁的异同、功能特性以及它们在实际应用中的适用场景。 首先,Synchronized是一种内置的Java关键字,它提供了简单而强大的线程同步机制。当一个线程进入一个由...
1. **线程互斥**:当一个线程在执行`synchronized`代码时,其他线程必须等待该线程释放锁后才能进入。 2. **内存可见性**:确保线程在读取或修改共享变量时,能看到其他线程对变量的最新修改,避免数据不一致。 3. *...
当一个线程访问某个对象的一个`synchronized`方法时,它就获得了该对象的锁,并且其他线程无法再访问该对象的其他`synchronized`方法。 - **互斥性**:通过`synchronized`关键字实现的锁具有互斥性,也就是说,一次...
当一个线程进入某个对象的一个`synchronized`代码块时,它会自动获得该对象的锁;离开该代码块时,则自动释放锁。如果其他线程尝试访问同一对象的其他`synchronized`代码块,它们将被阻塞,直到第一个线程释放锁为止...
当`synchronized`用于修饰代码块时,需要指定一个锁对象。这使得开发者可以更精细地控制锁的范围,避免不必要的性能损失。 ```java public class MyClass { private Object lock = new Object(); private int ...
- **锁机制**:当一个线程进入`synchronized`代码块或方法时,会自动获取锁;离开时,自动释放锁。 - **互斥性**:同一时刻,只有一个线程可以拥有锁,其他试图获取锁的线程将被阻塞,直到锁被释放。 - **锁升级**:...
Java并发synchronized锁住的内容解析是Java并发编程中的一种重要机制,用于解决多线程并发访问同一个资源时可能出现的线程安全问题。通过使用synchronized关键字,可以锁住当前对象的当前方法,使得其他线程访问该...