java多线程之共享资源

转载请注明出处

http://blog.csdn.net/pony_maggie/article/details/42587821

作者:小马


先看一个示例, 多个计数器线程实例(TwoCounter), 每个实例有两个整型计数器,线程运行时,两个计数器开始"同时"累加,还有若干个监控器线程实例(Watcher),每个实例都会利用自己的"线程时间"监控所有的计数器实例,当某个实例中的count1和count2不相等时,就会显示"unsynched"。


贴出一些关键的代码,

class TwoCounter extends Thread
	{
		private boolean started = false;
		private JTextField t1 = new JTextField(5);
		private JTextField t2 = new JTextField(5);
		
		private JLabel label = new JLabel("count1 == count2");
		private int count1 = 0, count2 = 0;
		public TwoCounter()
		{
			JPanel p = new JPanel();
			p.add(t1);
			p.add(t2);
			p.add(label);
			getContentPane().add(p);
			
		}
		//为了防止同一个线程多次启动
		public void start()
		{
			if(!started)
			{
				started = true;
				super.start();
			}
		}
		
		public void run()
		{
			while(true)
			{
				t1.setText(Integer.toString(count1++));
				t2.setText(Integer.toString(count2++));
				try 
				{
					sleep(500);
				} 
				catch (InterruptedException e) 
				{
					System.err.println("Interrupted");
				}
			}
		}
		
		//用来监视计算器的对外API
		public void synchTest()
		{
			Sharing1.incrementAccess();//追踪访问次数
			if(count1 != count2)
			{
				label.setText("Unsynched");
			}
		}
	}




class Watcher extends Thread
	{
		public Watcher()
		{
			start();
		}
		public void run()
		{
			while(true)
			{
				for(int i = 0; i < s.length; i++)
				{
					s[i].synchTest();
				}
				try 
				{
					sleep(500);
				} 
				catch (InterruptedException e) 
				{
					System.err.println("interrupted");
				}
			}
		}
	}



这个demo的要演示的功能看起来有些匪夷所思,从代码上看,两个计数器应该是"永远"相等的,毕竟每个计数器实例是独立的,有自己的textField, label, 计数器并且同时累加,怎么会有不等的情况呢?


先看看运行的结果:


java多线程之共享资源_第1张图片       java多线程之共享资源_第2张图片

java多线程之共享资源_第3张图片



结果证明确实有不相等的情况出现,原因是什么呢?


再回头看一下TwoCounter中的run函数,线程的执行函数,下面两行:

t1.setText(Integer.toString(count1++));
t2.setText(Integer.toString(count2++));



一般情况下,这两行会"同时"(CPU中的同一个时间片)执行,这时count1和count2相等的情况。但是因为是多个线程,你永远不知道某个线程什么时候获取执行的机会, 有可能Watcher线程在t1和t2之间执行了,这个就是"不相等的情况"。


这个示例说明多线程在某些时候可能会给我们带来麻烦,有很多应用场景我们希望类似上面t1和t2要能同时执行,不然可能带来严重的后果。好在java有一种同步机制,可以解决这样的问题,下一篇接着讲。


你可能感兴趣的:(java,多线程,同步,资源,共享)