转载请注明出处

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, 计数器并且同时累加,怎么会有不等的情况呢?

先看看运行的结果:

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

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

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

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

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

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

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

返回
顶部