Thinking in Java学习笔记 synchronized同步方法和synchronized同步块

本文通过三个实例深入探讨了Java中对象的同步方法如何实现并发操作与互斥访问,详细展示了synchronized关键字在不同场景下的应用效果,包括同步方法、同步方法块以及多个方法之间的同步关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对象的两个synchronized方法被两个线程分别调用,在一个获取到锁的情况下,另一个synchronized方法需要等待第一个synchronized方法执行完毕才能获得锁开始执行。

也就是说,一个对象实例只有一个锁,所有的synchronized方法都要在获取到这一个锁的情况下才能执行,否则就要等待。


package com.test.concurrent;

public class SyncObject {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		testSyncFunc();
	}
	public static void testSyncFunc(){
		final DualSynch ds=new DualSynch();
		new Thread(){
			public void run(){
				try {
					ds.f1();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}.start();
		new Thread(){
			public void run(){
				try {
					ds.f2();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}.start();
	}

}
class DualSynch{
	private Object syncObject=new Object();<span style="white-space:pre">	</span>//需要定义为final
	public synchronized void f1() throws InterruptedException{
		for(int i=0;i<5;i++){
			System.out.println("f1()");
			syncObject=new String("object1");
			Thread.sleep(500);
			Thread.yield();
			System.out.println("f1:"+syncObject);
		}
	}
	public synchronized void f2() throws InterruptedException{
		syncObject=new String("object2");
		for(int i=0;i<5;i++){
			System.out.println("f2()");
			Thread.sleep(500);
			Thread.yield();
			System.out.println("f2:"+syncObject);
		}
	}
	public void g() throws InterruptedException{
		synchronized(syncObject){
			syncObject=new String("object--g");
			for(int i=0;i<5;i++){
				Thread.sleep(500);
			}
		}
	}
}

输出为:

f1()
f1:object1
f1()
f1:object1
f1()
f1:object1
f1()
f1:object1
f2()
f2:object2
f2()
f2:object2
f2()
f2:object2
f2()
f2:object2
f2()
f2:object2



第二个例子:

一个实例的synchronized方法和synchronized方法块是不冲突的,而且互相可以看到对方修改之后的变量

package com.test.concurrent;

public class SyncObject {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		testSyncFuncAndBlock();
	}
	public static void testSyncFuncAndBlock(){
		final DualSynch ds=new DualSynch();
		new Thread(){
			public void run(){
				try {
					ds.f1();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}.start();
		new Thread(){
			public void run(){
				try {
					ds.g();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}.start();
	}

}
class DualSynch{
	private Object syncObject=new Object();
	public synchronized void f1() throws InterruptedException{
		for(int i=0;i<5;i++){
			System.out.println("f1()");
			syncObject=new String("object1");
			Thread.sleep(500);
			Thread.yield();
			System.out.println("f1:"+syncObject);
		}
	}
	public void g() throws InterruptedException{
		synchronized(syncObject){
			syncObject=new String("object--g");
			for(int i=0;i<5;i++){
				System.out.println("g()");
				Thread.sleep(500);
				System.out.println("g:"+syncObject);
			}
		}
	}
}
输出:

f1()
g()
f1:object--g //synchronized代码块修改了变量后,synchronized方法显示了修改后的值
g:object--g
g()
f1()
f1:object1
f1()
g:object1 //synchronized方法修改了变量后,synchronized代码块显示了修改后的值
g()
g:object1
f1:object1
f1()
g()
g:object1
g()
f1:object1
f1()
f1:object1
g:object1

第三个例子:


两个方法分别包含不同的synchronized同步块,可以同时执行,且同时修改一个变量后可被对方看到

package com.test.concurrent;

public class SyncObject {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		testSyncFuncAndBlock();
	}
	public static void testSyncFuncAndBlock(){
		final DualSynch ds=new DualSynch();
		new Thread(){
			public void run(){
				try {
					ds.g1();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}.start();
		new Thread(){
			public void run(){
				try {
					ds.g2();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}.start();
	}

}
class DualSynch{
	private Object syncObject=new Object();
	
	public void g1() throws InterruptedException{
		synchronized(syncObject){
			syncObject=new String("object--g1");
			for(int i=0;i<5;i++){
				System.out.println("g1()");
				Thread.sleep(500);
				System.out.println("g1:"+syncObject);
			}
		}
	}
	public void g2() throws InterruptedException{
		synchronized(syncObject){
			syncObject=new String("object--g2");
			for(int i=0;i<5;i++){
				System.out.println("g2()");
				Thread.sleep(500);
				System.out.println("g2:"+syncObject);
			}
		}
	}
}

输出为:

g1()
g2()
g1:object--g2
g1()
g2:object--g2
g2()
g1:object--g2
g1()
g2:object--g2
g2()
g1:object--g2
g1()
g2:object--g2
g2()
g1:object--g2
g1()
g2:object--g2
g2()
g1:object--g2
g2:object--g2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值