Java多线程与并发库高级应用-可阻塞的队列
ArrayBlockQueue 可阻塞的队列
> 队列包含固定长度的队列和不固定长度的队列。
> ArrayBlockQueue
> 看BlockingQueue类的帮助文档,其中有各个方法的区别对比的表格。
> 只有put方法和 take 方法才具有阻塞功能
> 用3个空间的队列来演示阻塞队列的功能和效果
/* * 两个线程向队列中放数据,一个线程从队列中取数据 */ public class BlockingQueueTest {</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) { </span><span style="color: #0000ff">final</span> BlockingQueue queue = <span style="color: #0000ff">new</span> ArrayBlockingQueue(3<span style="color: #000000">); </span><span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i = 0;i<2;i++<span style="color: #000000">){ </span><span style="color: #0000ff">new</span><span style="color: #000000"> Thread(){ </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() { </span><span style="color: #0000ff">while</span>(<span style="color: #0000ff">true</span><span style="color: #000000">){ </span><span style="color: #0000ff">try</span><span style="color: #000000"> { Thread.sleep((</span><span style="color: #0000ff">long</span>)(Math.random()*1000<span style="color: #000000">)); System.out.println(Thread.currentThread().getName() </span>+"准备放数据"<span style="color: #000000">); queue.put(</span>1<span style="color: #000000">); System.out.println(Thread.currentThread().getName() </span>+"队列目前有"+queue.size()+"个数据"<span style="color: #000000">); } </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (Exception e) { e.printStackTrace(); } } }; }.start(); } </span><span style="color: #0000ff">new</span><span style="color: #000000"> Thread(){ </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() { </span><span style="color: #0000ff">while</span>(<span style="color: #0000ff">true</span><span style="color: #000000">){ </span><span style="color: #0000ff">try</span><span style="color: #000000"> { </span><span style="color: #008000">//</span><span style="color: #008000">将此处的睡眠时间分别改为100和1000,观察运行结果</span> Thread.sleep(1000<span style="color: #000000">); System.out.println(Thread.currentThread().getName() </span>+"准备取数据"<span style="color: #000000">); queue.take(); System.out.println(Thread.currentThread().getName() </span>+"队列目前有"+queue.size()+"个数据"<span style="color: #000000">); } </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (Exception e) { e.printStackTrace(); } } }; }.start(); }
}
>用两个具有1个空间的队列来实现同步通知的功能
/** * 改造之前的程序,用两个具有1个空间的队列来实现同步通知的功能 * 使用阻塞队列实现 * 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着又 主线程循环100次,如此循环50次,请写出程序 * * @author Administrator * */ public class BlockingQueueCommunication {</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) { </span><span style="color: #0000ff">final</span> Business5 business = <span style="color: #0000ff">new</span><span style="color: #000000"> Business5(); </span><span style="color: #0000ff">new</span> Thread(<span style="color: #0000ff">new</span><span style="color: #000000"> Runnable() { @Override </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() { </span><span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 1; i <= 50; i++<span style="color: #000000">) { business.sub(i); } } }).start(); </span><span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 1; i <= 50; i++<span style="color: #000000">) { business.main(i); } } </span><span style="color: #0000ff">static</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Business5 { BlockingQueue</span><Integer> queue1 = <span style="color: #0000ff">new</span> ArrayBlockingQueue<>(1<span style="color: #000000">); BlockingQueue</span><Integer> queue2 = <span style="color: #0000ff">new</span> ArrayBlockingQueue<>(1<span style="color: #000000">); </span><span style="color: #008000">//</span><span style="color: #008000">这种写法叫 匿名构造方法,运行时机在任何构造方法之前,创建多少个对象就会调用多少次, 而static{} 静态代码块在类加载的时候调用且只调用一次</span>
{
try {
queue2.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> sub(<span style="color: #0000ff">int</span><span style="color: #000000"> i) { </span><span style="color: #0000ff">try</span><span style="color: #000000"> { queue1.put(</span>1<span style="color: #000000">); } </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (InterruptedException e) { e.printStackTrace(); } </span><span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> j = 1; j <= 100; j++<span style="color: #000000">) { System.out.println(</span>"sub thread sequence of " + j + ", loop of " +<span style="color: #000000"> i); } </span><span style="color: #0000ff">try</span><span style="color: #000000"> { queue2.take(); } </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (InterruptedException e) { e.printStackTrace(); } } </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> main(<span style="color: #0000ff">int</span><span style="color: #000000"> i) { </span><span style="color: #0000ff">try</span><span style="color: #000000"> { queue2.put(</span>1<span style="color: #000000">); } </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (InterruptedException e) { e.printStackTrace(); } </span><span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> j = 1; j <= 10; j++<span style="color: #000000">) { System.out.println(</span>"main thread sequence of " +<span style="color: #000000"> j </span>+ ", loop of " +<span style="color: #000000"> i); } </span><span style="color: #0000ff">try</span><span style="color: #000000"> { queue1.take(); } </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (InterruptedException e) { </span><span style="color: #008000">//</span><span style="color: #008000"> TODO Auto-generated catch block</span>
e.printStackTrace();
}
}
}}