java同步机制及synchronized关键字的应用2

本文通过一个简单的测试程序展示了在Java中,当两个线程分别尝试访问同一个对象的两个不同的`synchronized`方法时会发生什么。实验结果显示,这两个方法的执行是互斥的,即一个方法开始执行后另一个方法必须等待。

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

类定义:

 

public class Test{
  public synchronized method1(){...}
  public synchronized method2(){...}
}

 

问题:

 

多线程并发访问method1和method2时,两者会互斥吗?

 

下面的测试程序来回答这个问题。

public class TestSynchronizedMethod {
	
	private void ivkMethod1(){
		Thread thread1 = new Thread() {
			public void run() {
				for(int i = 0; i < 20; i++) {
					//System.out.println("\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
					//System.out.println("~~~~ start thread method1 ");
					method1();
					//System.out.println("~~~~ end   thread method1 ");
				}
			}
		};
		
		thread1.start();
	}
	
	private void ivkMethod2(){
		Thread thread2 = new Thread() {
			public void run() {
				for(int i = 0; i < 20; i++) {
					//System.out.println("\n\n#################################################");
					//System.out.println("#### start thread method2 ");
					method2();
					//System.out.println("#### end   thread method2 ");
				}
			}
		};	
		
		thread2.start();
	}
	
	
	
	
	private synchronized void method1(){
		System.out.println("\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println("~~~~ enter method1");
		
		try{
			System.out.println("~~~~ method1 begin to sleep 10s");
			Thread.sleep(10000);
		}catch(Exception e){
			e.printStackTrace();
		}
		System.out.println("~~~~ method1 end sleep");
	}
	
	private synchronized void method2(){
		System.out.println("\n\n#################################################");
		System.out.println("#### enter method2");
		
		try{
			System.out.println("#### method2 begin to sleep 3s");
			Thread.sleep(3000);
		}catch(Exception e){
			e.printStackTrace();
		}
		System.out.println("#### method2 end sleep");
	}	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			TestSynchronizedMethod obj = new TestSynchronizedMethod();
			obj.ivkMethod1();
			obj.ivkMethod2();
			
		} catch (Exception e) {
			e.printStackTrace();
			
		} catch (Error er) {
			er.printStackTrace();
		}

	}

}

 

结论很明显,无需多言。究其原因,method1和method2所持的锁为obj实例锁,所以当对同一obj调用两个方法时,两者不能并发执行。编码时要注意这一点,这种情况下对象的并发能力比较差,可参考下java.util.Vector的get和set方法,就很容易理解为什么JDK新版本中提供了替代的List接口了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值