`
wandejun1012
  • 浏览: 2689972 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java synchronized 串行

    博客分类:
  • java
 
阅读更多

 

背景:大家都知道用synchronized来实现加锁,使得不会出现线程安全问题。

但是今天在研究一段经典的面试题时(2个线程++,2个线程--)的问题时,发现在一个类的2个方法上全加上synchronized时,所有的线程竟然变得串行了。

 

因此,研究了一下,发现原来是对象锁的原因,在方法上加上synchronized时,其实默认是占得了此对象的对象锁,而此对象锁是一个对象只有一把钥匙,因此当调用其中一个带synchronized的方法时,其余的线程都拿不到钥匙而只能等待。 

 

其中的一个反例就是,给此对象再加个方法,前面不带synchronized,就会发现,此方法不受对象锁的控制而随机出现,并非串行。

 

 

关键代码如下:

 

int i=0;
	int k=0;
        //带synchronized
	public synchronized void count(){
		for(int j=0;j<10;j++){
			i++;
			System.out.println(Thread.currentThread().getName()+"^_^count,i的值为"+i);
		}
	}
	
	
	
	//不带synchronized
	public void countForFree(){
		for(int j=0;j<10;j++){
			k++;
			System.out.println(Thread.currentThread().getName()+"^_^countForFree^_^,k的值为"+k);
		}
	}
	
	/**
	 * 1、用4个线程,分别访问2个带锁的方法,发现线程全部顺序执行,因为虽然是2个带锁的方法,但是对象锁的钥匙只有一把。
	 * 2、用2个线程,一个是访问有锁的方法,一个是访问无锁的方法,可以惊人的发现,线程又开始无序执行,说明无锁的方法不受对象锁的控制。
	 * @param args
	 */
	public static void main(String[] args) {

		SynchronizedTest synchronizedTest=new SynchronizedTest();
		new Thread(new MyThread(synchronizedTest)).start();
		/*new Thread(new MyThread(synchronizedTest)).start();
		new Thread(new MyThread(synchronizedTest)).start();
		new Thread(new MyThread(synchronizedTest)).start();*/
		new Thread(new FreeThread(synchronizedTest)).start();
		
	}

 

 

完整代码:git@git.oschina.net:iPhone2020/MultiThread.git

 

synchronized对象锁比喻成房子的钥匙的形象比喻:http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html

 

官方参考链接:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics