📄 java08_04.htm
字号:
<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Java程序设计</title>
</head>
<body background="Bg.gif">
<p align="center"><font size="5"><b>§8.4线程的同步与死锁</b></font></p>
<p align="left">
和进程一样,多线程的程序也要考虑各个线程之间的协调和配合。特别是当线程要共享资源时,就必须考虑线程之间的互斥、同步问题,如果编写不当,就有可能发生死锁。关于互斥、同步、死锁、临界区这些概念,在操作系统中已经讲得很清楚,请大家回顾。</p>
<p align="left">
在操作系统中,为了解决进程间的互斥、同步,必须要使用PV原语,而在Java中,系统提供了和PV原语类似的两个方法:<br>
public final void wait()<br>
public final void notify()<br>
以及配套使用的一个关键字:synchronized。</p>
<p align="left"> 注意,上面两个方法是object类的成员方法,由于该类是所有类的基类,所以在任何类中,可以直接使用这两个方法而无须用对象名.方法名()的格式。<br>
wait()是将本线程转入阻塞状态,它和sleep()不同,它会暂时释放占用的资源管程。notify()则是唤醒某个在管程队列中排队等候的线程。而synchronized关键字则用来标志被同步使用的资源,这里的资源既可以是数据,也可以是方法,甚至是一段代码。凡是被synchronized修饰的的代码段,系统都会为它分配一个管程,这样就能保证在某一时间内,只有一个线程在享有这一资源。</p>
<p align="left">
下面实现了操作系统中一个经典的问题:生产者-消费者问题。</p>
<p align="left">class common{<br>
private int production;<br>
private boolean signal=false;<br>
<br>
<b>synchronized</b> int get(){ //注意这个关键字<br>
int result;<br>
//下面这个相当于P原语<br>
if (!signal)<br>
try{<br>
wait();<br>
}catch(InterruptedException e) { }<br>
//下面这段相当于V原语<br>
signal=false; <br>
result=production;<br>
production=-1;<br>
notify();<br>
return result;<br>
}<br>
<br>
synchronized void put(int newproduct){<br>
if (signal)<br>
try{<br>
wait();<br>
}catch(InterruptedException e) { }<br>
production=newproduct;<br>
signal=true;<br>
notify(); <br>
} <br>
}</p>
<p align="left">class producer extends Thread{<br>
private common comm;<br>
public producer(common thiscomm){<br>
comm=thiscomm;<br>
}<br>
public void run(){<br>
int i;<br>
for(i=1;i<=100;i++)<br>
{ comm.put(i);<br>
System.out.println("生产的数据是:"+i);<br>
} <br>
}<br>
}<br>
</p>
<p align="left">class consumer extends Thread{<br>
private common comm; <br>
public consumer (common thiscomm){<br>
comm=thiscomm;<br>
}<br>
public void run(){<br>
int i,production;<br>
for(i=1;i<=100;i++)<br>
{ production=comm.get();<br>
System.out.println("得到的数据是:"+production);<br>
} <br>
} <br>
}<br>
</p>
<p align="left">public class producer_consumer{<br>
public static void main(String argv[]){<br>
common comm=new common();<br>
producer p=new producer(comm);<br>
consumer c=new consumer(comm);<br>
p.start();<br>
c.start();<br>
}<br>
}</p>
<p align="left">
从输出结果可以看到,它很好地解决了生产者线程和消费者线程间的同步问题。同学们可以依据此程序写出更为复杂的同步程序。</p>
<p align="left"><a href="index.htm">回目录</a> <a href="java08_03.htm">上一课</a>
</p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -