`

线程阻塞

阅读更多

线程阻塞队列

文章分类:Java编程

摘自别人,仅供分析
Java代码 复制代码 收藏代码
  1.   
  2. /*  
  3. 编写一个线程安全、大小固定的队列  
  4. 提供阻塞式的方法put,若队列没有空间,则方法put会一直等待  
  5. 提供阻塞式的方法take,若队列为空,则方法take会一直等待  
  6. 启动30个线程操作该队列,每个线程进行一次put和一次take操作    
  7. */  
  8.   
  9. /*  
  10. 已经按照顺序获得读锁和写锁了,但是如果启动30个线程的话,基本上每次都会死锁,线程都停在read_lock.wait()的位置,  
  11. 如果启动20个线程就只有一半的几率会死锁(其实都在等待read_lock的锁,不能说是死锁),但每一个线程take一次必然会put一次,  
  12. 或者反过来,按说是不会有都等待read_lock的情况  
  13. */  
  14.   
  15. package com.huawei.test;   
  16.   
  17. import java.util.*;   
  18.   
  19. public class Queue1   
  20. {   
  21.    final int SIZE = 10//队列固定大小   
  22.    ArrayList store = new ArrayList(SIZE);   
  23.   
  24.    Object write_lock = new Object();//用于对store的写操作,如get/add/set/remove   
  25.    Object read_lock = new Object(); //用于对store只读操作,如取size   
  26.   
  27.    public Queue1(){}   
  28.   
  29.    public void put (Object o) //没有空间一直等待   
  30.    {   
  31.        while(true){   
  32.            synchronized(read_lock){   
  33.                try{   
  34.                    if(store.size() == SIZE){   
  35.                        read_lock.wait();//如果队列已满,就释放锁   
  36.                    }else{   
  37.                        synchronized(write_lock){   
  38.                            Thread.sleep(50);   
  39.                            store.add(o); //增加元素到队列   
  40.                            System.out.println(Thread.currentThread().getName() + "****PUT::Size=" + store.size());   
  41.                            Thread.sleep(50);   
  42.                            read_lock.notifyAll(); //通知其他线程   
  43.                            break;   
  44.                          }   
  45.                    }   
  46.                }catch(Exception ex){   
  47.                        ex.printStackTrace(System.err);   
  48.                }   
  49.            }   
  50.        }   
  51.    }   
  52.   
  53.   
  54.    public Object take () //没有数据一直等待   
  55.    {   
  56.        while(true){   
  57.            synchronized(read_lock){   
  58.                try{   
  59.                    if(store.size() == 0){   
  60.                        read_lock.wait();//如果队列没有数据,就释放锁   
  61.                    }else{   
  62.                        synchronized(write_lock){   
  63.                            Thread.sleep(50);   
  64.                            Object obj = store.remove(0); //从队列头移走数据   
  65.                            System.out.println(Thread.currentThread().getName() + "****Take::Size=" + store.size());   
  66.                            Thread.sleep(50);   
  67.                            read_lock.notifyAll();//通知其他线程   
  68.                            return obj;   
  69.                        }   
  70.                    }   
  71.                }catch(Exception ex){   
  72.                    ex.printStackTrace(System.err);   
  73.                }   
  74.            }   
  75.        }   
  76.    }   
  77.   
  78.   
  79.    public static void main(String[] args){   
  80.        Queue1 queue1 = new Queue1(); //创建一个队列   
  81.   
  82.        for(int i = 0; i < 30; i++){ //启动30个线程访问队列   
  83.            TestThread thread = new TestThread(queue1,i);   
  84.            System.out.println( "--Thread:" + i + " Start!" );   
  85.            thread.start();   
  86.            try{   
  87.                Thread.sleep(10); //没隔十毫秒启动一个线程   
  88.            }catch(Exception ex){   
  89.                ex.printStackTrace(System.err);   
  90.            }   
  91.        }   
  92.    }   
  93.   
  94. }   
  95.   
  96.   
  97. class TestThread extends Thread   
  98. {   
  99.    Queue1 queue1 = null;   
  100.    int sn = 0;   
  101.   
  102.    public TestThread(Queue1 queue1,int sn){   
  103.        this.queue1 = queue1;   
  104.        this.sn = sn;   
  105.        setName("Thread::" + sn); //以序号作为线程名   
  106.    }   
  107.   
  108.    public void run(){   
  109.        String tmp = null;   
  110.        try{   
  111.            if( sn < 7){ //sn小于7的线程先put,后take   
  112.                tmp = "Thread-PUT::" + sn + "---put::";   
  113.                queue1.put(tmp);   
  114.                Thread.sleep(10);   
  115.                tmp = "Thread-Take::" + sn + "---take::";   
  116.                Object obj = queue1.take();   
  117.            }else//sn大于7的线程先take,后put   
  118.                tmp = "Thread-Take::" + sn + "---take::";   
  119.                Object obj = queue1.take();   
  120.                Thread.sleep(10);   
  121.                tmp = "Thread-PUT::" + sn + "---put::";   
  122.                queue1.put(tmp);   
  123.            }   
  124.            System.out.println("Thread::" + sn + " task over!");   
  125.        }catch(Exception ex){   
  126.            ex.printStackTrace(System.err);   
  127.        }   
  128.   
  129.    }   
  130. }  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics