Queue入门小案例
这篇文章不谈什么技术,只写几个线程和队列相关的入门小案例而已,有兴趣的朋友可以看看,没兴趣的可以就此打住.
public class QueueDemo {
public static void main(String[] args) {
// 创建一个双端队列
ArrayDeque<Object> deque = new ArrayDeque<>();
//添加元素
deque.offer("春花");
deque.offer("夏夜");
deque.offer("秋香");
deque.offer("冬梅");
//移出元素
// System.out.println(deque.poll());
// 从头部加元素
deque.addFirst("石榴");
// System.out.println(deque);
// 从尾部加元素
deque.addLast("武状元");
// System.out.println(deque);
for(int i=1;i<100;i++){
deque.offer("华安"+i);
}
//多线程测试,安全问题
for(int i=0;i<4;i++){
new ConsumeQueue(deque).start();;
}
}
}
//自定义线程
public class ConsumeQueue extends Thread{
private ArrayDeque<Object> deque;
public ConsumeQueue(ArrayDeque<Object> deque) {
this.deque = deque;
}
@Override
public void run() {
while(true){
System.out.println(Thread.currentThread().getId()+"......."+deque.poll());
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
多线程的运行结果:
说到线程,顺便说下线程,实现线程的方式有三种,第一种是上面用的继承Thread类,第二种是实现Runnable接口(可看之前的文章<<简单了解下多线程>>),第三种是java.util.concurrent下的Callable接口.
Callable入门小案例
public class CallableDemo {
public static void main(String[] args) throws Exception {
//1.实现Callable
Callable<String> callable=new Callable<String>() {
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "小淫虫周伯通";
}
};
//2.创建futureTask
FutureTask<String> futureTask = new FutureTask<String>(callable);
//3.执行
new Thread(futureTask).start();
try {
Thread.sleep(5000);
System.out.println(futureTask.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在查找相关api时,我发现在java.util.concurrent下,有一个队列叫BlockingQueue,即阻塞队列:
- 当队列满了的时候进行入队列操作
- 当队列空了的时候进行出队列操作
BlockingQueue小案例:
public class BlockQueueDemo {
public static void main(String[] args) throws Exception {
final BlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(100);
/*for(int i=0;i<11;i++){
//加多了会阻塞(队列容量为10)
blockingQueue.put("韦小宝"+i);
}
for(int i=0;i<20;i++){
//取多了也会阻塞(队列中只有10个值)
System.out.println(blockingQueue.take());
}*/
//多线程测试
//一个线程生产
new Thread(){
public void run() {
for(int i=1;i<100;i++){
try {
blockingQueue.put("韦小宝"+i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
//两个线程在消费
new Thread(){
public void run() {
while(true){
try {
System.out.println(Thread.currentThread().getId()+"...."+blockingQueue.take());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
new Thread(){
public void run() {
while(true){
try {
System.out.println(Thread.currentThread().getId()+"...."+blockingQueue.take());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
}
}
添加的元素大于队列容量时的阻塞
将队列中优速的元素都移除后也会阻塞
既然说到线程,那就说一下线程池
线程池入门小案例:
//线程池
public class ThreadPoolDemo {
//固定线程池,底层是无界队列
@Test
public void testFixedThreadPool(){
//创建6个线程
ExecutorService threadPool = Executors.newFixedThreadPool(6);
for(int i=0;i<6;i++){
threadPool.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getId()+"风华绝代石榴姐");
}
});
}
}
//单一线程,在执行任务时,会依次执行,底层是无界队列
@Test
public void testSingleThreadExecutor(){
//创建6个线程
ExecutorService threadPool = Executors.newSingleThreadExecutor();
for(int i=0;i<6;i++){
threadPool.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getId()+"武功盖世武状元");
System.out.println(System.currentTimeMillis());
}
});
}
}
//创建非固定数量,可缓存的线程池,当提交的任务起起伏伏时,会自动创建或减少执行线程数量
@Test
public void testCachedThread(){
//创建6个线程
ExecutorService threadPool = Executors.newCachedThreadPool();
for(int i=0;i<50;i++){
threadPool.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getId()+"绝命书生一点红");
System.out.println(System.currentTimeMillis());
}
});
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("--------------------------------------------------");
for(int i=0;i<10;i++){
threadPool.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getId()+"遛鸟狂魔发飙王");
System.out.println(System.currentTimeMillis());
}
});
}
}
//后面还有定时执行线程池等,有想要了解的可以去练下,我不多写了.....
}