初試java_thread生產者消費者
自己給自己想了個題目,1個線程生產筆,1個線程取,在1箱轉滿10個的時候取走
分析:client 和service線程共享一個盒子變量, ,線程共享會涉及到 線程鎖機制 ,目前我掌握的線程鎖,主要是通過 java關鍵字 synchronized,synchronized可以鎖對象,方法,鎖某塊
比如syschronized (對象){
do some thing
}
鎖方法 public synchronized void test()
{
}
}
一、當兩個并發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以后才能執行該代碼塊。
二、當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
三、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的除synchronized(this)同步代碼塊以外的部分。
四、第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。
五、以上規則對其它對象鎖同樣適用
如果要保證線程的有序執行,還的加上wait() ,notify()的方法配和
wait()方法,將線程進入阻塞隊列,釋放鎖資源,等待其他的線程喚醒,
notify()方法,喚醒阻塞隊列中的線程,進入就緒隊列,
下面我試驗的列子
Box是共享變量 ,
public class Box {
private int size=100;
private ArrayList list=new ArrayList();
public synchronized boolean put(Pen p)
{
if(list.size()>=size) //不能放
{
try{
System.out.println("放滿等待取走...");
wait();
}catch(Exception e)
{
e.printStackTrace();
} return false;
}
list.add(p);
this.notify();//喚醒阻塞隊列的某線程到就序隊列
return true;
}
public synchronized void get()
{
//如果>size那就取走,
if(list.size()>=size)
{ int j=list.size();
list.clear();
System.out.println("取走了");
this.notify();//喚醒阻塞隊列的某線程到就序隊列
}else
try{
wait();
}catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String []args)
{
Box box=new Box();
prodThread prodthread=new prodThread(box);
prodthread.start();
clientThread client=new clientThread(box);
client.start();
}
private ArrayList list=new ArrayList();
public synchronized boolean put(Pen p)
{
if(list.size()>=size) //不能放
{
try{
System.out.println("放滿等待取走...");
wait();
}catch(Exception e)
{
e.printStackTrace();
} return false;
}
list.add(p);
this.notify();//喚醒阻塞隊列的某線程到就序隊列
return true;
}
public synchronized void get()
{
//如果>size那就取走,
if(list.size()>=size)
{ int j=list.size();
list.clear();
System.out.println("取走了");
this.notify();//喚醒阻塞隊列的某線程到就序隊列
}else
try{
wait();
}catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String []args)
{
Box box=new Box();
prodThread prodthread=new prodThread(box);
prodthread.start();
clientThread client=new clientThread(box);
client.start();
}
public class clientThread extends Thread {
private Box box;
int i=0;
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
box.get();
//System.out.println("getJ==="+i);
i=i+1;
}
}
public clientThread(Box box)
{
this.box=box;
}
int i=0;
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
box.get();
//System.out.println("getJ==="+i);
i=i+1;
}
}
public clientThread(Box box)
{
this.box=box;
}
}
public class prodThread extends Thread {
private Box b;
private int i=0;
public prodThread(Box box)
{
this.b=box;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
Pen p=new Pen();
if(b.put(p))
{ i=i+1;
//System.out.println("添加成功i=="+i);
}
/* else
try{//休眠
this.sleep(5000l);
}catch(Exception e)
{
e.printStackTrace();
}
*/
//super.run();
}
}
public static void main(String []args)
{
}
}
結果:
private Box b;
private int i=0;
public prodThread(Box box)
{
this.b=box;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
Pen p=new Pen();
if(b.put(p))
{ i=i+1;
//System.out.println("添加成功i=="+i);
}
/* else
try{//休眠
this.sleep(5000l);
}catch(Exception e)
{
e.printStackTrace();
}
*/
//super.run();
}
}
public static void main(String []args)
{
}
}
結果:
放滿等待取走...
取走了
放滿等待取走...
取走了
放滿等待取走...
取走了
取走了
放滿等待取走...
取走了
放滿等待取走...
取走了
如果不加 wait(),notify將是無序的
本文由用戶 chyx413332087 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!