Java多线程与并发库高级应用-可阻塞的队列

ArrayBlockQueue 可阻塞的队列

  > 队列包含固定长度的队列和不固定长度的队列。

  > ArrayBlockQueue

    > 看BlockingQueue类的帮助文档,其中有各个方法的区别对比的表格。

    > 只有put方法和 take 方法才具有阻塞功能

  > 用3个空间的队列来演示阻塞队列的功能和效果

Java多线程与并发库高级应用-可阻塞的队列
/*
 * 两个线程向队列中放数据,一个线程从队列中取数据
 */
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&lt;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();
}

}

Java多线程与并发库高级应用-可阻塞的队列

   >用两个具有1个空间的队列来实现同步通知的功能

Java多线程与并发库高级应用-可阻塞的队列
/**
 * 改造之前的程序,用两个具有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 &lt;= 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 &lt;= 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>&lt;Integer&gt; queue1 = <span style="color: #0000ff">new</span> ArrayBlockingQueue&lt;&gt;(1<span style="color: #000000">);
    BlockingQueue</span>&lt;Integer&gt; queue2 = <span style="color: #0000ff">new</span> ArrayBlockingQueue&lt;&gt;(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 &lt;= 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 &lt;= 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();
}
}
}

}

Java多线程与并发库高级应用-可阻塞的队列

ArrayBlockQueue 可阻塞的队列

  > 队列包含固定长度的队列和不固定长度的队列。

  > ArrayBlockQueue

    > 看BlockingQueue类的帮助文档,其中有各个方法的区别对比的表格。

    > 只有put方法和 take 方法才具有阻塞功能

  > 用3个空间的队列来演示阻塞队列的功能和效果

Java多线程与并发库高级应用-可阻塞的队列
/*
 * 两个线程向队列中放数据,一个线程从队列中取数据
 */
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&lt;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();
}

}

Java多线程与并发库高级应用-可阻塞的队列

   >用两个具有1个空间的队列来实现同步通知的功能

Java多线程与并发库高级应用-可阻塞的队列
/**
 * 改造之前的程序,用两个具有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 &lt;= 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 &lt;= 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>&lt;Integer&gt; queue1 = <span style="color: #0000ff">new</span> ArrayBlockingQueue&lt;&gt;(1<span style="color: #000000">);
    BlockingQueue</span>&lt;Integer&gt; queue2 = <span style="color: #0000ff">new</span> ArrayBlockingQueue&lt;&gt;(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 &lt;= 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 &lt;= 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();
}
}
}

}

Java多线程与并发库高级应用-可阻塞的队列