有关synchronized同步的问题

    今天看到了一个有关synchronized的题,自己也是正在复习JAVA基础知识。

class Test{
	synchronized static void sayHello3(){
		synchronized void getX(){
	}
}

问的是这两个方法同步吗?

    首先我们应该理解问这个题目的意思,题上问的是这两个方法是不是同步的,这两个方法一个是静态方法,一个是普通方法,但是他们都被synchronized关键字修饰,他们本身当然是同步的,但是题目意思仔细想想并不是这个意思,而是说这两个方法是否同步。

    这两个方法都被synchronized修饰,这两个方法是否同步,问题在于他们所持有的锁是否相同,由于第一个方法时静态方法,他持有的锁应该是Test.class,而第二个方法时普通方法,他所持有的锁应该是Test类创建的实例对象,即this。由于这两个方法持有的锁是不同的,那这两个方法就不是同步的。

SynchronizedJava中解决并发问题的常用方法,其作用主要有确保线程互斥的访问同步代码、保证共享变量的修改能够及时可见以及有效解决重排序问题[^1]。 ### 原理 Java虚拟机中的同步基于进入和退出Monitor对象实现,无论是显式同步(有明确的monitorenter和monitorexit指令,即同步代码块)还是隐式同步都是如此。对于同步方法,并不是由monitorenter和monitorexit指令来实现同步的,而是由方法调用指令读取运行时常量池中方法表结构的ACC_SYNCHRONIZED标志来隐式实现的[^3]。 ### 使用方法 从语法上讲,Synchronized总共有三种用法: - **修饰实例方法**:作用于当前实例加锁,进入同步代码前要获得当前实例的锁。例如: ```java public synchronized void add(int number){ sum=sum+number; } ``` 这种方式每个实例其方法同步同步在不同的对象上,即该方法所属的实例。多个线程对同一个实例的同步块进行调用时,同一时刻只有一个线程在调用;如果有多个实例,多个线程分别对不同的实例同步块进行调用互不影响,不会造成等待[^1][^2]。 - **修饰静态方法**:作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁[^1]。 - **修饰代码块**:指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁[^1]。 ### 应用场景 - **线程互斥访问**:当多个线程需要访问共享资源时,使用synchronized可以确保同一时刻只有一个线程能够访问该资源,避免数据竞争和不一致问题。例如,多个线程对同一个计数器进行操作时,可以使用synchronized来保证计数器的正确性。 - **共享变量可见性**:synchronized可以保证共享变量的修改能够及时可见。当一个线程修改了共享变量的值,其他线程在进入同步块时能够看到最新的值。 - **解决重排序问题**:在多线程环境下,编译器和处理器可能会对指令进行重排序,导致程序的执行结果不符合预期。synchronized可以有效解决重排序问题,保证程序的执行顺序符合代码的逻辑顺序。 - **线程间协作**:通过wait()和notify()方法synchronized可以实现线程间的协作。wait()方法可以使处于临界区内的线程进入阻塞状态,同时释放被同步对象的控制权;notify()方法可以唤醒一个因调用了wait()操作而处于阻塞状态中的线程,使其进入就绪状态[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值