黑马程序员技术交流社区
标题:
等待唤醒机制和CPU背后的故事,纯技术贴!
[打印本页]
作者:
赵玮_Tom
时间:
2012-5-14 20:32
标题:
等待唤醒机制和CPU背后的故事,纯技术贴!
学完多线程技术,并了解了线程和CPU的运行原理。可以利用等待唤醒机制来控制线程得到或放弃CPU执行权。那么,
不借助等待唤醒机制,我们是否也能实现对多线程的控制,达到相同效果呢?
可能你会认为这是痴人说梦。但仔细看完下面的程序,希望能对多线程有更深的了解。
/*
该例没有使用”等待唤醒“机制,却依然实现了多线程对同一资源进行操作的效果(当然效率比使用等待唤醒机制的时候要低)。
*/
class Res
{
/*定义flag变量,用于标记生产者和消费者的
动作交替。如果flag为true,生产者可以进行
”生产“,消费者不能进行”消费“;反之,亦然。*/
private boolean flag=true;
/*定义mark变量,用于标记生产的内容。如果
mark为true,生产”张三“,如果mark为false,
生产”rose“。*/
boolean mark = true;
/*定义count指针,用于给生产的信息编号*/
private int count = 1;
private String name;
private String sex;
//同步方法,用于生产者设置信息。
public synchronized void setInfo(String name, String sex)
{
/*首先判断flag标记。注:在flag为false的情况下,即使消费者线程得到
CPU执行权,也不会执行任何动作*/
if(flag)
{
this.name=name+(count++);
this.sex=sex;
System.out.println(Thread.currentThread().getName()+"——生产了:"+this.name+"-----"+this.sex);
flag=false;//改变flag标记
mark=(mark==true)?false:true;//改变mark标记
}
}
//同步方法,用于消费者获取信息
public synchronized void getInfo()
{
/*首先判断flag标记。注:在flag为true的情况下,即使生产者线程得到
CPU执行权,也不会执行任何动作*/
if(!flag)
{
System.out.println(Thread.currentThread().getName()+"——消费了:"+this.name+"-----"+this.sex);
flag=true;//改变flag标记
}
}
}
class Producer implements Runnable
{
private Res res;
public Producer(Res res)
{
this.res=res;
}
public void run()
{
while(true)
{
if(res.mark)//mark为true,生产”张三“
{
res.setInfo("张三", "男");
}
else//mark为false,生产”rose“
{
res.setInfo("rose", "female");
}
}
}
}
class Consumer implements Runnable
{
private Res res;
public Consumer(Res res)
{
this.res=res;
}
public void run()
{
while(true)//消费者消费”信息“
{
res.getInfo();
}
}
}
public class ThreadDemo02
{
public static void main(String args [])
{
Res res = new Res();
//创建两个生产者线程和两个消费者线程
Producer p1 = new Producer(res);
Producer p2 = new Producer(res);
Consumer c1 = new Consumer(res);
Consumer c2 = new Consumer(res);
new Thread(p1).start();
new Thread(p2).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
复制代码
重点说明:
多线程对同一资源操作的问题中,有两点是至关重要的:
1)CPU工作原理:CPU是以极高的频率在多个线程之间做着快速的切换,并不是长时间只执行一个线程。
2)定义资源标记:这里说的“资源标记”就是boolean型变量,它的变化记录着该由哪些线程执行操作,哪些线程不该执行操作。
该例中涉及到两个“资源标记”:flag和mark。flag用于记录该对资源进行生产操作还是消费操作的情况。mark用于记录该生产哪种类型的产品(“张三”或“rose ”)。
只要定义好这两个“标记”,即使不借助等待唤醒机制,也可以实现多个生产者和多个消费者对同一资源进行操作的效果。
当然,这个程序的执行效率要低于加入等待唤醒机制的程序。因为正常程序中,线程遇到wait()会释放执行资格。该程序中却不存在释放执行资格的情况,而是借助CPU的快速切换实现效果。
该例目的在于使大家明白,
实现多线程对同一资源进行操作时,并不是必须要利用等待唤醒机制,只是一般程序都要提高效率,故等待唤醒这种机制会使用地比较普遍。
附执行效果图。期待交流。
Thread.png
(10.45 KB, 下载次数: 51)
下载附件
2012-5-14 20:32 上传
作者:
索学超
时间:
2012-5-14 20:37
顶一个。。。。
作者:
崔陈喜
时间:
2012-5-14 21:58
顶起,顶起!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2