Java线程同步问题

        使用synchronized同步方法和同步代码块,当是两个线程调用同一对象里面的synchronized方法或者代码块时,或者另外不是synchronized方法的时候,会是什么情况呢?

public class Orange {
	private int numOne=10;
	private int numtwo=10;	
	public synchronized  void test1()   {
		
		while(numOne>0) {
			System.out.println("我是方法test1的numOne:"+numOne--);
			try {
				Thread.sleep(1000);				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	public synchronized  void test2()   {
			
			while(numtwo>0) {
				System.out.println("我是方法test2的numtwo:"+numtwo--);				
				
			}
			
		}


}

public class Run1 implements Runnable{
	private Orange orange;
	public Run1(Orange orange) {
		this.orange=orange;
	}
	@Override
	public void run() {
		orange.test1();
		
	}
}
public class Run2 implements Runnable{
	private Orange orange;
	public Run2(Orange orange) {
		this.orange=orange;
	}
	@Override
	public void run() {
		orange.test2();
		
	}
}
public static void main(String[] args){

        Orange orange = new Orange();
	new Thread(new Run1(orange)).start();
	new Thread(new Run2(orange)).start();

}

输出:
我是方法test1的numOne:10
我是方法test1的numOne:9
我是方法test1的numOne:8
我是方法test1的numOne:7
我是方法test1的numOne:6
我是方法test1的numOne:5
我是方法test1的numOne:4
我是方法test1的numOne:3
我是方法test1的numOne:2
我是方法test1的numOne:1
我是方法test2的numtwo:10
我是方法test2的numtwo:9
我是方法test2的numtwo:8
我是方法test2的numtwo:7
我是方法test2的numtwo:6
我是方法test2的numtwo:5
我是方法test2的numtwo:4
我是方法test2的numtwo:3
我是方法test2的numtwo:2
我是方法test2的numtwo:1
        由上分析,在test1方法中sleep了1000毫秒,但是另外一个线程仍旧不去执行test2方法, 两个线程共用一个Orange对象,因此可以知道,当有不同线程调用同一对象的synchronized同步方法时,另外一个线程调用同一对象的其他synchronized同步方法时,会进入阻塞状态,既第一个线程首先获得了对象锁,因而另外一个线程无法取得该对象锁,从而进入阻塞状态。

        如果同步代码块会怎么样呢?把Orange类的test2方法改成同步代码块,其他代码不变。

public class Orange {
	private int numOne=10;
	private int numtwo=10;
	Fruit fruit=new Fruit();
	
	public synchronized  void test1()   {
		
		while(numOne>0) {
			System.out.println("我是方法test1的numOne:"+numOne--);
			try {
				Thread.sleep(1000);				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	
	public void test2() {
		synchronized (this) {
			while (numtwo>0) {
				System.out.println("我是方法test2的numtwo:"+numtwo--);
				
			}
		}
	}
	

}
输出:

我是方法test1的numOne:10
我是方法test1的numOne:9
我是方法test1的numOne:8
我是方法test1的numOne:7
我是方法test1的numOne:6
我是方法test1的numOne:5
我是方法test1的numOne:4
我是方法test1的numOne:3
我是方法test1的numOne:2
我是方法test1的numOne:1
我是方法test2的numtwo:10
我是方法test2的numtwo:9
我是方法test2的numtwo:8
我是方法test2的numtwo:7
我是方法test2的numtwo:6
我是方法test2的numtwo:5
我是方法test2的numtwo:4
我是方法test2的numtwo:3
我是方法test2的numtwo:2
我是方法test2的numtwo:1
        通过观察输出,发现跟上面的输出是一样的,从而知道synchronized(this)也是获得同一对象锁的,this指向当前对象,因而是同一个对象,如果把synchronized(this)里面的this改成其他对象呢?又会怎么样?

package com.qrj.bean;

public class Orange {
	private int numOne=10;
	private int numtwo=10;
	String strObj=new String();
	
	public synchronized  void test1()   {
		
		while(numOne>0) {
			System.out.println("我是方法test1的numOne:"+numOne--);
			try {
				Thread.sleep(1000);				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	
	public void test2() {
		synchronized (strObj) {
			while (numtwo>0) {
				System.out.println("我是方法test2的numtwo:"+numtwo--);
				
			}
		}
	}
	

}
输出:

我是方法test1的numOne:10
我是方法test2的numtwo:10
我是方法test2的numtwo:9
我是方法test2的numtwo:8
我是方法test2的numtwo:7
我是方法test2的numtwo:6
我是方法test2的numtwo:5
我是方法test2的numtwo:4
我是方法test2的numtwo:3
我是方法test2的numtwo:2
我是方法test2的numtwo:1
我是方法test1的numOne:9
我是方法test1的numOne:8
我是方法test1的numOne:7
我是方法test1的numOne:6
我是方法test1的numOne:5
我是方法test1的numOne:4
我是方法test1的numOne:3
我是方法test1的numOne:2
我是方法test1的numOne:1
        通过观察输出,第一个线程首先执行了一次test1方法循环,然后sleep(1000),但仍旧持有该对象锁,但是从输出发现,这时候第二个线程执行了test2方法,而test2的同步代码块是synchronized(strObj),不再是this了,因而没有阻塞,就可以干点别的事情了。

        那另外的线程可不可以执行同一对象的其他没有同步的方法而不进入不阻塞状态呢?把test2方法的同步代码块改一下,其他代码不变。

public void test2() {
		
			while (numtwo>0) {
				System.out.println("我是方法test2的numtwo:"+numtwo--);
				
			}
		}

输出:

我是方法test1的numOne:10
我是方法test2的numtwo:10
我是方法test2的numtwo:9
我是方法test2的numtwo:8
我是方法test2的numtwo:7
我是方法test2的numtwo:6
我是方法test2的numtwo:5
我是方法test2的numtwo:4
我是方法test2的numtwo:3
我是方法test2的numtwo:2
我是方法test2的numtwo:1
我是方法test1的numOne:9
我是方法test1的numOne:8
我是方法test1的numOne:7
我是方法test1的numOne:6
我是方法test1的numOne:5
我是方法test1的numOne:4
我是方法test1的numOne:3
我是方法test1的numOne:2
我是方法test1的numOne:1

        通过输出知道,另外的线程可以执行同一对象的没有同步(synchronized)的方法而不进入阻塞状态,不用等待第一个线程执行的同步方法结束后才执行。


如有不正之处,还望多多指正~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值