JAVA实现多线程生产者消费者模型

  • 问题背景: 做一个爬虫,从网上爬书籍,爬下来以后插入数据库

 

  • 问题设计: 用多个线程同时从网上爬书,爬下来的书使用一个线程作为插入,这些线程共享同一个书籍队列,并且同时开始运行

书籍POJO

package thread;
 
 public class Book {
     private Integer bookId;
     private String bookName;
 
     public Integer getBookId() {
         return bookId;
     }
 
     public void setBookId(Integer bookId) {
         this.bookId = bookId;
     }
 
     public String getBookName() {
         return bookName;
     }
 
     public void setBookName(String bookName) {
         this.bookName = bookName;
     }
 }

爬虫线程

package thread;
 
 import java.util.List;
 import java.util.Queue;
 
 public class CrawlerThread extends Thread {
     private List<Integer> bookIdList;   //待爬书籍的Id号
     private Queue<Book> bookQueue;  //爬完书籍的共享存储队列
 
     public CrawlerThread(List<Integer> bookIdList, Queue<Book> bookQueue) {
         this.bookIdList = bookIdList;
         this.bookQueue = bookQueue;
     }
 
     public void run() {
         for(int i = 0; i < bookIdList.size(); i++) {
             Book book = new Book(); //把这两步当做爬虫爬书的过程
             book.setBookId(bookIdList.get(i));
             book.setBookName("书名" + book.getBookId());
 
             try {
                 sleep((long) (Math.random() * 1000 * 1000));  //随机sleep 100 - 1000 秒,模拟爬虫爬书时的延时过程
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
 
             bookQueue.offer(book);  //爬完的书籍插入共享队列
         }
     }
 }

插入线程

package thread;
 
 import java.util.Queue;
 
 public class InsertThread extends Thread {
     private Queue<Book> bookQueue;  //爬完书籍的共享存储队列
 
     public InsertThread(Queue<Book> bookQueue) {
         this.bookQueue = bookQueue;
     }
 
     public void run() {
         int timer = 0; //超时计时器
 
         while(timer < 30) { //如果连续30分钟bookQueue均为空,则超时,线程结束
             if(bookQueue.size() != 0) { //如果队列不为空
                 Book book;
                 while((book = bookQueue.poll()) != null) {
                     System.out.println(book.getBookName()); //把这步当成插入数据库吧
                 }
                 timer = 0;  //超时计时器清零
             } else {
                 try {
                     sleep(60 * 1000);   //等待爬虫一分钟
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 timer++;    //timer时间+1
             }
         }
     }
 }

主程序

package thread;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 public class Start {
     public void main(String[] args) {
         Queue<Book> bookQueue = new ConcurrentLinkedQueue<Book>();  //使用线程安全的队列作为共享书籍队列
 
         //构造待爬书籍Id号
         List<Integer> bookIdList = new ArrayList<Integer>();
         bookIdList.add(1);
         bookIdList.add(2);
         bookIdList.add(3);
         bookIdList.add(4);
         bookIdList.add(5);
 
         CrawlerThread ct = new CrawlerThread(bookIdList, bookQueue);    //此处你可以将Id列表分为多分,分配给多个线程爬,我就不写了,懒..- -
         InsertThread it = new InsertThread(bookQueue);  //插入数据库线程
 
         ct.start();
         it.start();
     }
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值