Java中線程的通信
線程的同步解決了異步訪問共享數據時處理的不安全和數據不一致的問題,但是這還是遠遠不夠的,線程之間還需要相互通信,相互通知消息以便協同完成工作。在Java中線程的通信是通過wait(),notify(),notifyAll()等方法來完成的,這些方法都是Object類的方法,在Java中每個對象內部除了有一個對象鎖外還有一個等待隊列,這個隊列存放了所有對待這個對象鎖的線程。
以生產者消費者問題爲例,代碼如下:
public class ThreadCommunication
{
public static void main(String[] args)
{
Queue q = new Queue();
Producer p = new Producer(q);
Consumer c = new Consumer(q);
p.start();
c.start();
}
}
class Producer extends Thread
{
Queue q;
Producer(Queue q)
{
this.q = q;
}
public void run()
{
for(int i=0;i<10;i++)
{
q.put(i);
System.out.println("Producer put "+i);
}
}
}
class Consumer extends Thread
{
Queue q;
Consumer(Queue q)
{
this.q = q;
}
public void run()
{
while(true)
{
System.out.println("comsumer get "+ q.get());
}
}
}
class Queue
{
int value = 0;
boolean isFull = false;
public synchronized void put(int v) // wait 必須在Synchronized方法或synchronized塊中使用
{
if (!isFull)
{
value = v;
isFull = true;
notify();
}
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public synchronized int get() // wait 必須在Synchronized方法或synchronized塊中使用
{
if (!isFull)
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
isFull = false;
notify();
return value;
}
}
以生產者消費者問題爲例,代碼如下:
public class ThreadCommunication
{
public static void main(String[] args)
{
Queue q = new Queue();
Producer p = new Producer(q);
Consumer c = new Consumer(q);
p.start();
c.start();
}
}
class Producer extends Thread
{
Queue q;
Producer(Queue q)
{
this.q = q;
}
public void run()
{
for(int i=0;i<10;i++)
{
q.put(i);
System.out.println("Producer put "+i);
}
}
}
class Consumer extends Thread
{
Queue q;
Consumer(Queue q)
{
this.q = q;
}
public void run()
{
while(true)
{
System.out.println("comsumer get "+ q.get());
}
}
}
class Queue
{
int value = 0;
boolean isFull = false;
public synchronized void put(int v) // wait 必須在Synchronized方法或synchronized塊中使用
{
if (!isFull)
{
value = v;
isFull = true;
notify();
}
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public synchronized int get() // wait 必須在Synchronized方法或synchronized塊中使用
{
if (!isFull)
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
isFull = false;
notify();
return value;
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.