一个多线程的PushbackInputStream问题

07-06-25 computerboy
最近在更改以前老项目的代码,出了一个问题,

一部分代码:

class mythread extends Thread{

/**

被start()方法调用的主线程方法.

**/

public void run()

{

dbwr();

}

/**

该方法完成读文件,分析文件,插库,删除文件等全部功能.被线程主方法run()调用.

**/

public synchronized void dbwr()

{

// File news = new File("./store/");

/**

读入(./store/)路径

**/

//File news = new File("./store/");

File news = new File("f:/store/");

/**

存放所读的文件对象.

**/

File arry[];

arry=news.listFiles();

int delete_i=0;

try{

if(arry.length<1){

this.sleep(60000);

sernews.insertthread();

this.stop();this.destroy();

}

this.sleep(1000);

/**

一个用于判断文件是否结束的字节,如果结束,会自动返回-1.

**/

byte temp[]=new byte[1];

/**

读入没条新闻的分类个数.

**/

byte class_total[]=new byte[4];

/**

读入新闻类别.

**/

byte class_id[]=new byte[4];

/**

新闻的日期.

**/

byte news_date[]=new byte[4];

/**

新闻时间

**/

byte news_time[]=new byte[4];

/**

新闻标题的长度.

**/

byte title_total[]=new byte[4];

/**

新闻标题

**/

byte news_title[]=new byte[1024];

/**

新闻内容

**/

byte news_content[]=new byte[653600];

/**

新闻ID号,每条新闻去当前数据库中最大的ID号.

**/

long news_id=0;

for(int i=0;i<arry.length;i++){

delete_i=i;

System.out.print("文件名: "+arry.getName());

if(!arry.isFile()){

arry.delete();

continue;

}

if(arry.length()<40){

System.out.println("非法文件, 被删除!");

arry.delete();

continue;

}

/**

把当前的文件文件流的形式打开.

**/

FileInputStream inputfile=new FileInputStream(arry);

/**

把文件流实例化成一个反压流.

反压流---该流的指针能随文件的读入而移动.而且能够返回以读完的流的指针向量.

**/

PushbackInputStream readfile=new PushbackInputStream(inputfile,653600);

readfile.read(class_total,0,4);

int class_total_l=toInt(class_total);

if(class_total_l>10){

inputfile.close();

readfile.close();

// readfile.unread(class_total,0,4);

System.out.println("非法文件, 被删除!");

arry.delete();

continue;

}

/**

用于存储数据库的链接串,分别是hostname,port,SID,username,password.

**/

Class.forName("oracle.jdbc.driver.OracleDriver");

/**

建立JDBC的连接.

**/

Connection conn= DriverManager.getConnection ("jdbc:oracle:thin:@"+sernews.jdbcdrive,sernews.username,sernews.psw);

// Connection conn= DriverManager.getConnection ("jdbc:oracle:thin:@e5500:1521:ora815","xc","xc");

//Connection conn= DriverManager.getConnection ("jdbc:oracle:thin:@172.20.83.170:1521:ora9i","xc","xc");

conn.setAutoCommit(false);

/**

JDBC声明.

**/

Statement stmt = conn.createStatement();

/**

JDBC返回结果集.

**/

ResultSet result = stmt.executeQuery("select max(news_id) from t_news_class_1");

if(result.next()){

news_id=result.getLong(1);

news_id=news_id+1;

}

int class_id_l;

for(int j=0;j<class_total_l;j++){

readfile.read(class_id,0,4);

class_id_l=toInt(class_id);

stmt.execute("insert into t_news_class_1(news_id,news_class_id) values("+news_id+","+class_id_l+")");

// stmt.execute("insert into t_news_class_1_all(news_id,news_class_id) values("+news_id+","+class_id_l+")");

}

readfile.read(news_date,0,4);

/**

把字节型的日期转换成一个整形的数值.

**/

int lDate_value=toInt(news_date);

readfile.read(news_time,0,4);

/**

把字节型的时间转换成一个整形的数值.

**/

int lTime_value=toInt(news_time);

/**

把整型的日期转换成一个字符.

**/

String sundate=String.valueOf(lDate_value);

/**

把整型的时间转换成一个字符.

**/

String suntime=String.valueOf(lTime_value);

int len=suntime.length();

if(len<6)

{

for(int j=0;j<(6-len);j++)

suntime="0"+suntime;

}

computerboy
2007-06-25 16:58
/**

把日期转换成yyyymmddhh24miss的字符形式.

**/

String zdate_str=sundate+suntime;

if(!isDate(zdate_str)) {

inputfile.close();

readfile.close();

System.out.println("非法文件, 被删除!");

arry.delete();

continue;

}

/**

存储一个数据库SQL语句的日期类型.

**/

String date_value="to_date('"+zdate_str+"','yyyymmddhh24miss')";

readfile.read(title_total,0,4);

/**

存储新闻标题的长度知.

**/

int title_total_i=toInt(title_total);

readfile.read(news_title,0,title_total_i);

/**

新闻标题

**/

String news_title_value=new String(news_title,0,title_total_i);

news_title_value=news_title_value.replace('\'',''');

/**

新闻内容的长度.

**/

int news_content_int=0;

while(readfile.read(temp,0,1)!=-1){

news_content[news_content_int++]=temp[0];

}

/**

新闻内容.

**/

// String news_content_value=new String(news_content,0,news_content_int-1);

String news_content_value = new String(news_content).trim();

/**

插入数据库的SQL语句.

**/

String insert_info_content ="insert into t_news_content_1(news_id,news_time,news_release,news_title,news_content) values("+news_id+","+date_value+","+1+",'"+news_title_value+"',empty_clob())";

System.out.println("insert_info_content:"+insert_info_content);

// String insert_info_content1 ="insert into t_news_content_1_all(news_id,news_time,news_release,news_title,news_content) values("+news_id+","+date_value+","+1+",'"+news_title_value+"',empty_clob())";

stmt = conn.createStatement ();

stmt.execute(insert_info_content);

// stmt.execute(insert_info_content1);

/**

用如查询ORACLE数据库的CLOB字段的结果集.

**/

OracleResultSet ors = (OracleResultSet)stmt.executeQuery("select news_content from t_news_content_1 where news_id ="+news_id+" for update");

if(ors.next())

{

/**

新闻内容的CLOB值.

**/

CLOB clob = ors.getCLOB(1);

clob.putString(1,news_content_value);

System.out.println("news_content_value:"+news_content_value);

}else{

this.stop();this.destroy();

}

/* ors = (OracleResultSet)stmt.executeQuery("select news_content from t_news_content_1_all where news_id ="+news_id+" for update");

if(ors.next())

{

// 新闻内容的CLOB值.

CLOB clob = ors.getCLOB(1);

clob.putString(1,news_content_value);

}else{

this.stop();this.destroy();

} */

System.out.print("插入成功..... ");

ors=null;

// rd.close();

inputfile.close();

readfile.close();

//ostmt.close();

conn.close();

stmt.close();

result.close();

System.out.println(arry.getName()+"被删除");

arry.delete();

}

sernews.insertthread();

this.stop();

this.destroy();

}

catch(IOException e)

{

System.out.println(e);

arry[delete_i].delete();

sernews.insertthread();

this.stop();

this.destroy();

}

catch(SQLException e)

{

try{

this.sleep(6000);

}catch(Exception ex){}

System.out.println("数据库中断......");

sernews.insertthread();

this.stop();

this.destroy();

}

catch(Exception e)

{ System.out.println("有异常发生,忽略.....");

sernews.insertthread();

this.stop();

this.destroy();

}

}

这个是通过一个多线程的形式读入的,

但是遇到一个问题,就是在读入一个文件的时候,放在缓存里了。

写入数据库,当读第二个文件时,不知道为什么,第一个文件的缓存没有清理干净。导致在写第二个文件的时候,第一个还有一部分也写入到第二个文件的下边了。

这个问题是对于读3k的文件就不行。不知道什么原因,还请大家帮我看看 。谢谢,在线等。

banq
2007-06-25 18:05
>是在读入一个文件的时候,放在缓存里了。

>写入数据库,当读第二个文件时,不知道为什么,第一个文件的缓存没有清理干净。>导致在写第二个文件的时候,第一个还有一部分也写入到第二个文件的下边了。

两个线程分享一个缓存,当然会冲突了。

两个解决方向:

1. 同步锁定缓存,某个时刻只能有一个线程访问读取,读取完清空。

2. 每个线程每个缓存,可以使用threadlocal试看。

computerboy
2007-06-26 09:21
banq 大哥能给一个具体方面的实现么,

我对线程这块不是那么熟悉的。

还望大家帮忙一下,谢谢

猜你喜欢