NutzCN Logo
问答 多线程插入数据库数据,报错了。求大神给看看。
发布于 2904天前 作者 mingkaili 6350 次浏览 复制 上一个帖子 下一个帖子
标签:

异常如下:
2016-05-12 19:22:27,067 [org.nutz.dao.impl.sql.run.NutDaoExecutor:org.nutz.dao.impl.sql.run.NutDaoExecutor._runPreparedStatement(NutDaoExecutor.java:254)] INSERT INTO mv_qizhou_search(goodsId,name,marketPrice,shopPrice,goodsType,cateId,destId,lastUpdate,goodsBrief,imgThumb,imgUrl,imgSmall) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|------|----------------------|----|-------|----|----|-----|---------------------|--------------------------|-----------------------------------------------------------------------|------------------------------------------------------------------------|-----------------------------------------------------------------------|
| 6711 | 拉斯维加斯西峡谷直升机之旅(直升机往返) | ¥0 | ¥3309 | 34 | 20 | 332 | 2016-05-12 17:01:00 | 从拉斯维加斯乘坐直升机出发,一路看风景到达西峡谷 | http://res.7zhou.com/images/201605/goods_img/6711_G_1462981309630.jpg | http://res.7zhou.com/images/201605/source_img/6711_G_1462981309739.jpg | http://res.7zhou.com/images/201605/goods_img/6711_G_1462981309630.jpg |
For example:> "INSERT INTO mv_qizhou_search(goodsId,name,marketPrice,shopPrice,goodsType,cateId,destId,lastUpdate,goodsBrief,imgThumb,imgUrl,imgSmall) VALUES(6711,'拉斯维加斯西峡谷直升机之旅(直升机往返)','¥0','¥3309',34,20,332,'2016-05-12 17:01:00','从拉斯维加斯乘坐直升机出发,一路看风景到达西峡谷','http://res.7zhou.com/images/201605/goods_img/6711_G_1462981309630.jpg','http://res.7zhou.com/images/201605/source_img/6711_G_1462981309739.jpg','http://res.7zhou.com/images/201605/goods_img/6711_G_1462981309630.jpg') "
2016-05-12 19:23:17,126 [org.nutz.dao.impl.sql.run.NutDaoExecutor:org.nutz.dao.impl.sql.run.NutDaoExecutor.exec(NutDaoExecutor.java:89)] SQLException
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:493)
at org.nutz.dao.impl.sql.run.NutDaoExecutor._runPreparedStatement(NutDaoExecutor.java:268)
at org.nutz.dao.impl.sql.run.NutDaoExecutor.exec(NutDaoExecutor.java:82)
at org.nutz.dao.impl.DaoSupport$DaoExec.invoke(DaoSupport.java:316)
at org.nutz.dao.impl.sql.run.NutDaoRunner.run(NutDaoRunner.java:59)
at org.nutz.dao.impl.DaoSupport.run(DaoSupport.java:239)
at org.nutz.dao.impl.DaoSupport._exec(DaoSupport.java:271)
at org.nutz.dao.impl.EntityOperator.exec(EntityOperator.java:50)
at org.nutz.dao.impl.NutDao.insert(NutDao.java:158)
at com.mxlvniao.lvniao.qizhou.thread.QizhouDownloadThread.insertObj(QizhouDownloadThread.java:123)
at com.mxlvniao.lvniao.qizhou.thread.QizhouDownloadThread.run(QizhouDownloadThread.java:79)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
org.nutz.dao.DaoException: !Nutz SQL Error: 'INSERT INTO mv_qizhou_search(goodsId,name,marketPrice,shopPrice,goodsType,cateId,destId,lastUpdate,goodsBrief,imgThumb,imgUrl,imgSmall) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|------|----------------------|----|-------|----|----|-----|---------------------|--------------------------|-----------------------------------------------------------------------|------------------------------------------------------------------------|-----------------------------------------------------------------------|
| 6711 | 拉斯维加斯西峡谷直升机之旅(直升机往返) | ¥0 | ¥3309 | 34 | 20 | 332 | 2016-05-12 17:01:00 | 从拉斯维加斯乘坐直升机出发,一路看风景到达西峡谷 | http://res.7zhou.com/images/201605/goods_img/6711_G_1462981309630.jpg | http://res.7zhou.com/images/201605/source_img/6711_G_1462981309739.jpg | http://res.7zhou.com/images/201605/goods_img/6711_G_1462981309630.jpg |
For example:> "INSERT INTO mv_qizhou_search(goodsId,name,marketPrice,shopPrice,goodsType,cateId,destId,lastUpdate,goodsBrief,imgThumb,imgUrl,imgSmall) VALUES(6711,'拉斯维加斯西峡谷直升机之旅(直升机往返)','¥0','¥3309',34,20,332,'2016-05-12 17:01:00','从拉斯维加斯乘坐直升机出发,一路看风景到达西峡谷','http://res.7zhou.com/images/201605/goods_img/6711_G_1462981309630.jpg','http://res.7zhou.com/images/201605/source_img/6711_G_1462981309739.jpg','http://res.7zhou.com/images/201605/goods_img/6711_G_1462981309630.jpg') "'
PreparedStatement:
'INSERT INTO mv_qizhou_search(goodsId,name,marketPrice,shopPrice,goodsType,cateId,destId,lastUpdate,goodsBrief,imgThumb,imgUrl,imgSmall) VALUES(?,?,?,?,?,?,?,?,?,?,?,?) '
CaseMessage=Lock wait timeout exceeded; try restarting transaction
at org.nutz.dao.impl.sql.run.NutDaoExecutor.exec(NutDaoExecutor.java:96)
at org.nutz.dao.impl.DaoSupport$DaoExec.invoke(DaoSupport.java:316)
at org.nutz.dao.impl.sql.run.NutDaoRunner.run(NutDaoRunner.java:59)
at org.nutz.dao.impl.DaoSupport.run(DaoSupport.java:239)
at org.nutz.dao.impl.DaoSupport._exec(DaoSupport.java:271)
at org.nutz.dao.impl.EntityOperator.exec(EntityOperator.java:50)
at org.nutz.dao.impl.NutDao.insert(NutDao.java:158)
at com.mxlvniao.lvniao.qizhou.thread.QizhouDownloadThread.insertObj(QizhouDownloadThread.java:123)
at com.mxlvniao.lvniao.qizhou.thread.QizhouDownloadThread.run(QizhouDownloadThread.java:79)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:493)
at org.nutz.dao.impl.sql.run.NutDaoExecutor._runPreparedStatement(NutDaoExecutor.java:268)
at org.nutz.dao.impl.sql.run.NutDaoExecutor.exec(NutDaoExecutor.java:82)
... 11 more
2016-05-12 19:23:17,135 [org.nutz.dao.impl.sql.run.NutDaoExecutor:org.nutz.dao.impl.sql.run.NutDaoExecutor._runPreparedStatement(NutDaoExecutor.java:254)] INSERT INTO mv_qizhou_search(goodsId,name,marketPrice,shopPrice,goodsType,cateId,destId,lastUpdate,goodsBrief,imgThumb,imgUrl,imgSmall) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|------|----------------|------|------|----|----|-----|---------------------|-----------------------------------------------------|-----------------------------------------------------------------------|------------------------------------------------------------------------|-----------------------------------------------------------------------|
| 6704 | 的的喀喀湖2日游(普诺出发) | ¥710 | ¥589 | 34 | 20 | 726 | 2016-05-10 01:31:00 | 安第斯山脉文明的重要摇篮,印加和艾马拉人心中神话般的地方。花2天时光沉浸在这片湖中,探寻丰富的秘鲁历史 | http://res.7zhou.com/images/201605/goods_img/6704_G_1462784682188.jpg | http://res.7zhou.com/images/201605/source_img/6704_G_1462784682235.jpg | http://res.7zhou.com/images/201605/goods_img/6704_G_1462784682188.jpg |
For example:> "INSERT INTO mv_qizhou_search(goodsId,name,marketPrice,shopPrice,goodsType,cateId,destId,lastUpdate,goodsBrief,imgThumb,imgUrl,imgSmall) VALUES(6704,'的的喀喀湖2日游(普诺出发)','¥710','¥589',34,20,726,'2016-05-10 01:31:00','安第斯山脉文明的重要摇篮,印加和艾马拉人心中神话般的地方。花2天时光沉浸在这片湖中,探寻丰富的秘鲁历史','http://res.7zhou.com/images/201605/goods_img/6704_G_1462784682188.jpg','http://res.7zhou.com/images/201605/source_img/6704_G_1462784682235.jpg','http://res.7zhou.com/images/201605/goods_img/6704_G_1462784682188.jpg') "

代码如下:
主程序:
private void downloadQizhouSearch(JSONObject jsonAccessToken)
throws Exception {

// ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors
// .newCachedThreadPool();

    List<MvQizhouCategory> listCategory = dao.query(MvQizhouCategory.class,
         null);

    dao.clear(MvQizhouSearch.class);

    for (int j = 0; j < listCategory.size(); j++) {
       MvQizhouCategory mvQizhouCategory = listCategory.get(j);

       JSONObject jsonPara = new JSONObject();
       jsonPara.put("access_token", jsonAccessToken);

       JSONObject filter = new JSONObject();
       filter.put("category_id", mvQizhouCategory.getId());
       jsonPara.put("filter", filter);

       JSONObject pagination = new JSONObject();
       pagination.put("count", 1);
       pagination.put("page", 1);
       jsonPara.put("pagination", pagination);

       Map<String, Object> mapPara = new HashMap<String, Object>();
       mapPara.put("json", jsonPara.toString());
       String result = Http.post("http://open.7zhou.com/search", mapPara,
          30000);
       log.debug("name:" + mvQizhouCategory.getName()
          + "=======计算总数=======result:" + result);

       JSONObject jsonResult = JSONObject.fromObject(result);
       int total = jsonResult.getJSONObject("paginated").getInt("total");
       int pageCount = total % 10000 > 0 ? total / 10000 + 1
          : total / 10000;
       log.debug("total=" + total + "-------" + "pageCount=" + pageCount);
       CountDownLatch doneSignal = new CountDownLatch(pageCount);
       Executor executor = Executors.newFixedThreadPool(5);
       for (int page = 1; page <= pageCount; page++) {
         String threadName = "name:" + mvQizhouCategory.getName()
              + "----" + "pageNo:" + page;
         QizhouDownloadThread command = new QizhouDownloadThread(doneSignal, dao,
              threadName, mvQizhouCategory, jsonAccessToken, page);
         executor.execute(command);
       }
       doneSignal.await();
    }

// threadPool.shutdown();
}

线程
package com.mxlvniao.lvniao.qizhou.thread;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.nutz.dao.Dao;
import org.nutz.http.Http;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import com.mxlvniao.entity.dao.mv.MvQizhouCategory;
import com.mxlvniao.entity.dao.mv.MvQizhouSearch;

public class QizhouDownloadThread implements Runnable {
private static final Log log = Logs.get();

private static final String QIZHOU_PIC_URL_OLD = "http://open.7zhou.com";
private static final String QIZHOU_PIC_URL_NEW = "http://res.7zhou.com";

private CountDownLatch doneSignal;
private Dao dao;
private String threadName;
private MvQizhouCategory mvQizhouCategory;
private JSONObject jsonAccessToken;
private int page;

public QizhouDownloadThread(CountDownLatch doneSignal, Dao dao,
       String threadName, MvQizhouCategory mvQizhouCategory,
       JSONObject jsonAccessToken, int page) {
    this.doneSignal = doneSignal;
    this.dao = dao;
    this.threadName = threadName;
    this.mvQizhouCategory = mvQizhouCategory;
    this.jsonAccessToken = jsonAccessToken;
    this.page = page;
}

@Override
public void run() {
    try {
       log.debug("线程Name:" + threadName + "******开始*******");

       JSONObject jsonPara = new JSONObject();
       jsonPara.put("access_token", jsonAccessToken);
       JSONObject filter = new JSONObject();
       filter.put("category_id", mvQizhouCategory.getId());
       jsonPara.put("filter", filter);

       JSONObject pagination = new JSONObject();
       pagination.put("count", 10000);
       pagination.put("page", page);
       jsonPara.put("pagination", pagination);

       Map<String, Object> mapPara = new HashMap<String, Object>();
       mapPara.put("json", jsonPara.toString());

       String result = Http.post("http://open.7zhou.com/search", mapPara,
          60000);

       JSONObject jsonResult = JSONObject.fromObject(result);
       if (!jsonResult.containsKey("status")
          || jsonResult.getJSONObject("status").getInt("succeed") == 0) {
         log.debug("线程Name:" + threadName
              + "==========查询结果不正确或为空=============");
         return;
       }

       if (jsonResult.getJSONObject("status").getInt("succeed") == 1) {
         JSONArray dataArr = jsonResult.getJSONArray("data");
         for (int i = 0; i < dataArr.size(); i++) {
          try {
              JSONObject obj = dataArr.getJSONObject(i);
              insertObj(obj);
          } catch (Exception e) {
              e.printStackTrace();
              continue;
          }
         }
       }

       log.debug("线程Name:" + threadName + "******结束*******");

    } catch (Exception e) {
       e.printStackTrace();
    } finally {
       if (doneSignal != null) {
         doneSignal.countDown();
       }
    }
}

private void insertObj(JSONObject obj) throws Exception {

    MvQizhouSearch mvQizhouSearch = new MvQizhouSearch();
    mvQizhouSearch.setGoodsId(obj.getInt("goods_id"));
    mvQizhouSearch.setName(obj.getString("name"));
    mvQizhouSearch.setMarketPrice(obj.getString("market_price"));
    mvQizhouSearch.setShopPrice(obj.getString("shop_price"));
    mvQizhouSearch.setGoodsType(obj.getInt("goods_type"));
    mvQizhouSearch.setCateId(mvQizhouCategory.getId());
    mvQizhouSearch.setDestId(obj.getInt("dest_id"));
    SimpleDateFormat longFormatterWithHyphen2 = new SimpleDateFormat(
         "yyyy-MM-dd HH:mm");
    Date lastUpdate = longFormatterWithHyphen2.parse(obj
         .getString("last_update"));
    if (lastUpdate == null)
       return;
    mvQizhouSearch.setLastUpdate(lastUpdate);
    mvQizhouSearch.setGoodsBrief(obj.getString("goods_brief"));
    mvQizhouSearch.setImgThumb(obj.getJSONObject("img").getString("thumb")
         .replace(QIZHOU_PIC_URL_OLD, QIZHOU_PIC_URL_NEW));
    mvQizhouSearch.setImgUrl(obj.getJSONObject("img").getString("url")
         .replace(QIZHOU_PIC_URL_OLD, QIZHOU_PIC_URL_NEW));
    mvQizhouSearch.setImgSmall(obj.getJSONObject("img").getString("small")
         .replace(QIZHOU_PIC_URL_OLD, QIZHOU_PIC_URL_NEW));

    dao.insert(mvQizhouSearch);
}

}

15 回复

pojo贴出来

package com.mxlvniao.entity.dao;

import java.io.Serializable;
import java.util.Date;

import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Name;
import org.nutz.dao.entity.annotation.One;
import org.nutz.dao.entity.annotation.Table;

@Table("tb_commodity")
public class Commodity implements Serializable {
private static final long serialVersionUID = 1L;

@Name
private String id;
@Column
private String destId;
@Column
private String cateId;
@Column
private Long poiId;
@Column
private String name;
@Column
private String qizhouId;
@Column
private String qizhouGoodsType;
@Column
private double marketPrice;
@Column
private double shopPrice;
@Column
private Date lastUpdate;
@Column
private String brief;
@Column
private String picId;
@Column
private String url;
@One(target = Destination.class, field = "destId")
private Destination destination;
@One(target = Category.class, field = "cateId")
private Category category;
@One(target = Poi.class, field = "poiId")
private Poi poi;
@One(target = CommodityPic.class, field = "picId")
private CommodityPic img;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getDestId() {
    return destId;
}

public void setDestId(String destId) {
    this.destId = destId;
}

public String getCateId() {
    return cateId;
}

public void setCateId(String cateId) {
    this.cateId = cateId;
}

public Long getPoiId() {
    return poiId;
}

public void setPoiId(Long poiId) {
    this.poiId = poiId;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getQizhouId() {
    return qizhouId;
}

public void setQizhouId(String qizhouId) {
    this.qizhouId = qizhouId;
}

public String getQizhouGoodsType() {
    return qizhouGoodsType;
}

public void setQizhouGoodsType(String qizhouGoodsType) {
    this.qizhouGoodsType = qizhouGoodsType;
}

public double getMarketPrice() {
    return marketPrice;
}

public void setMarketPrice(double marketPrice) {
    this.marketPrice = marketPrice;
}

public double getShopPrice() {
    return shopPrice;
}

public void setShopPrice(double shopPrice) {
    this.shopPrice = shopPrice;
}

public Date getLastUpdate() {
    return lastUpdate;
}

public void setLastUpdate(Date lastUpdate) {
    this.lastUpdate = lastUpdate;
}

public String getBrief() {
    return brief;
}

public void setBrief(String brief) {
    this.brief = brief;
}

public String getPicId() {
    return picId;
}

public void setPicId(String picId) {
    this.picId = picId;
}

public String getUrl() {
    return url;
}

public void setUrl(String url) {
    this.url = url;
}

public Destination getDestination() {
    return destination;
}

public void setDestination(Destination destination) {
    this.destination = destination;
}

public Category getCategory() {
    return category;
}

public void setCategory(Category category) {
    this.category = category;
}

public Poi getPoi() {
    return poi;
}

public void setPoi(Poi poi) {
    this.poi = poi;
}

public CommodityPic getImg() {
    return img;
}

public void setImg(CommodityPic img) {
    this.img = img;
}

}

是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊是这个啊

package com.mxlvniao.entity.dao.mv;

import java.io.Serializable;
import java.util.Date;

import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Table;

@Table("mv_qizhou_search")
public class MvQizhouSearch implements Serializable {
private static final long serialVersionUID = 1L;

@Id(auto=false)
private Integer goodsId;
@Column
private String name;
@Column
private String marketPrice;
@Column
private String shopPrice;
@Column
private Integer goodsType;
@Column
private Integer cateId;
@Column
private Integer destId;
@Column
private Date lastUpdate;
@Column
private String goodsBrief;
@Column
private String imgThumb;
@Column
private String imgUrl;
@Column
private String imgSmall;

public Integer getGoodsId() {
    return goodsId;
}

public void setGoodsId(Integer goodsId) {
    this.goodsId = goodsId;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getMarketPrice() {
    return marketPrice;
}

public void setMarketPrice(String marketPrice) {
    this.marketPrice = marketPrice;
}

public String getShopPrice() {
    return shopPrice;
}

public void setShopPrice(String shopPrice) {
    this.shopPrice = shopPrice;
}

public Integer getGoodsType() {
    return goodsType;
}

public void setGoodsType(Integer goodsType) {
    this.goodsType = goodsType;
}

public Integer getCateId() {
    return cateId;
}

public void setCateId(Integer cateId) {
    this.cateId = cateId;
}

public Integer getDestId() {
    return destId;
}

public void setDestId(Integer destId) {
    this.destId = destId;
}

public Date getLastUpdate() {
    return lastUpdate;
}

public void setLastUpdate(Date lastUpdate) {
    this.lastUpdate = lastUpdate;
}

public String getGoodsBrief() {
    return goodsBrief;
}

public void setGoodsBrief(String goodsBrief) {
    this.goodsBrief = goodsBrief;
}

public String getImgThumb() {
    return imgThumb;
}

public void setImgThumb(String imgThumb) {
    this.imgThumb = imgThumb;
}

public String getImgUrl() {
    return imgUrl;
}

public void setImgUrl(String imgUrl) {
    this.imgUrl = imgUrl;
}

public String getImgSmall() {
    return imgSmall;
}

public void setImgSmall(String imgSmall) {
    this.imgSmall = imgSmall;
}

}

是不是还有其他线程在查?导致锁表了?

@wendal 这个应该没有 ,一共就生成了一个线程就这样了。主代码for循环的最外面那层,第一次进入以后,里面的for循环就循环一次,就生成了一个线程,然后,就停止在doneSignal.await();这里,然后,那一个线程就开始在线程的那个类里面执行,然后就报这个错了。

@wendal 我查了一下数据库,确实死锁了。但不知道是哪里出毛病了。

这句不应该在for循环之外吗???

 doneSignal.await();

@mingkaili 你现在是写在for循环之内了

@wendal
for (int j = 0; j < listCategory.size(); j++) {
MvQizhouCategory mvQizhouCategory = listCategory.get(j);

   String result = Http.post("http://open.7zhou.com/search", mapPara,
      30000);

   JSONObject jsonResult = JSONObject.fromObject(result);
   int total = jsonResult.getJSONObject("paginated").getInt("total");
   int pageCount = total % 10000 > 0 ? total / 10000 + 1
      : total / 10000;

  ** CountDownLatch doneSignal = new CountDownLatch(pageCount);
   Executor executor = Executors.newFixedThreadPool(5);**
   *for (int page = 1; page <= pageCount; page++) {
     String threadName = "name:" + mvQizhouCategory.getName()
          + "----" + "pageNo:" + page;
     QizhouDownloadThread command = new QizhouDownloadThread(doneSignal, dao,
          threadName, mvQizhouCategory, jsonAccessToken, page);
     executor.execute(command);
   }*
  ** doneSignal.await();**
}

CountDownLatch这个对象我是在第一层for循环内创建的,线程池也是在那里创建的,当然是要写到第一for循环内啊。

@wendal
我现在要是把dao.insert(mvQizhouSearch);这句话注释掉的话,就可以完全执行成功。没有出现死锁。要是不注释掉就会死锁了。
昨天我查到这个,http://blog.sina.com.cn/s/blog_4bed7e340101atnf.html
里面是这么说的。
**Executors.newFixedThreadPool这是个有固定活动线程数。当提
交到池中的任务数大于固定活动线程数时,任务就会放到阻塞队列中等待。
主任务和子任务都放到了线程池中,就有下面的情况发生,
主任务调用一次CountDownLatch实例的await()方法时,当前线程就会一直占用一个活动线程,如果多次调用,
那么就会一直占用多个活动线程,如果调用次数大于固定活动线程数,那么就可能造成阻塞队列
中某些子任务一直不被执行,CountDownLatch实例的countDown()的方法一直不被调用,那么对应的
主任务所在线程就会无限等待,与死锁现像一样

解决办法是避免主任务不要和子任务放到同一线程池

另外还有另外一种情况,就是子任务有可以因为其它原因,不去执行CountDownLatch实例的
countDown()方法,造成主任务所在线程无限等待

解决办法是最好不要用CountDownLatch实例的await(),归避长时间阻塞线程的风险,任何多线程应用程序都有死锁风险,改用CountDownLatch实例的await(long timeout, TimeUnit unit),设定超时时间,如果超时,
将返回false,这样我们得知超时后,可以做异常处理,而await()是void类型,没有返回值,
我们无法得知超时信息**

我感觉他说得比较对,但是CountDownLatch按照他说的就不能用了啊 ?那岂不是这个类太鸡肋了。。。求大神帮我参谋参谋。

for循环里面创建线程池, 而且用完还不close,这是搞毛线

不过, 这种事情, 还是得需要自行简化, 去掉一切多余的代码, 简化出能重现问题的最少代码来

线程池, 一般是作为实例变量/静态变量, 只创建很少的次数的, 不然还叫线程池干啥.

另外, dao.insert和dao.fastInsert都支持传集合的, 后者是batch批量插入.

@wendal 现在就是找不到那个占用表的地方。不知道是哪里占用的,一直不释放。
这个代码确实有点多。我再写个例子试一试。

@wendal 懂了 我改一下插入方式。

@wendal 改成批量插入一下子就好了,没有毛病了。这是为啥啊 ?我有点蒙。

添加回复
请先登陆
回到顶部