Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程应用程序将重复行写入日志文件_Java_Regex_Multithreading - Fatal编程技术网

Java 线程应用程序将重复行写入日志文件

Java 线程应用程序将重复行写入日志文件,java,regex,multithreading,Java,Regex,Multithreading,我已经编写了一个多线程应用程序,它使用regex分析数据库中的行并适当地更新它们。我正在将每一行写入一个日志文件以用于日志记录。我注意到同一行被多次写入日志文件…有时甚至超过15次。下面是代码片段 设置ThreadPoolExecuter: private static BlockingQueue<Runnable> worksQueue = new ArrayBlockingQueue<Runnable>(blockingQueueSize); private stat

我已经编写了一个多线程应用程序,它使用regex分析数据库中的行并适当地更新它们。我正在将每一行写入一个日志文件以用于日志记录。我注意到同一行被多次写入日志文件…有时甚至超过15次。下面是代码片段

设置ThreadPoolExecuter:

private static BlockingQueue<Runnable> worksQueue = new ArrayBlockingQueue<Runnable>(blockingQueueSize);
private static ThreadPoolExecutor exec = new ThreadPoolExecutor(threadPoolSize, threadPoolSize, 10, TimeUnit.SECONDS, worksQueue);
UpdateMember(仅显示run和writeToLog方法):

公共类UpdateMember实现可运行{
结果集rs;
连接接头;
文件编写器;
公共更新成员(结果集、连接连接、FileWriter fw){
这1.rs=rs;
this.conn=conn;
this.fw=fw;
}
@凌驾
公开募捐{
试一试{
(a-a-a-zA-Z-Z\\\\...........)10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10“;QC | PC |魁|魁北克| SK |萨斯克|萨斯喀彻温| YT |育空|育空地区(\\s(?CA | CAN | canda))?”;
Pattern=Pattern.compile(regex,Pattern.CASE不区分大小写);
BigDecimal memrecno=rs.getBigDecimal(2);
String addressLineTwo=rs.getString(4);
字符串addressLineThree=rs.getString(5);
字符串地址linefour=rs.getString(6);
BigDecimal attrrecno=rs.getBigDecimal(9);
字符串addressBeingParsed=“”;
字符串city=null;
字符串省=空;
字符串country=null;
布尔usingAddressThree=假;
布尔值usingAddressFour=false;
如果(addressLineFour==null){
if(addressLineThree==null){
city=“未知”;
}
其他的
{
addressBeingParsed=addressLineThree;
usingAddressThree=真;
}
}
其他的
{
addressBeingParsed=addressLineFour;
usingAddressFour=真;
}
如果(使用地址三| |使用地址四){
Matcher Matcher=pattern.Matcher(正在解析的地址);
//如果找到匹配项
if(matcher.matches()){
城市=匹配器组(“城市”);
省=匹配器组(“州”);
国家=匹配器组(“国家”);
if(city==null | | city.isEmpty()){
//城市只是字母字符和空间
字符串cityRegex=“(?^[a-zA-Z\\s\\.]+$)”;
Pattern cityPattern=Pattern.compile(cityRegex,Pattern.Pattern不区分大小写);
如果(使用AddressFour&&(addressLineThree!=null)&&!addressLineThree.isEmpty()){
Matcher cityMatcher=cityPattern.Matcher(addressLineThree);
if(cityMatcher.matches()){
城市=城市匹配器组(“城市”);
}
其他的
{
city=“未知”;
}
}
else if(使用AddressThree&&(addressLineTwo!=null)&&!addressLineTwo.isEmpty()){
Matcher cityMatcher=cityPattern.Matcher(addressLineTwo);
if(cityMatcher.matches()){
城市=城市匹配器组(“城市”);
}
其他的
{
city=“未知”;
}
}
其他的
{
city=“未知”;
}
}
if(province!=null&&!province.isEmpty()){
省=createProvinceCode(省);
}
}
其他的
{
city=“未知”;
}
}
//更新数据库中的属性
布尔值success=updateRow(memrecno、attrecno、市、省);
字符串logLine=memrecno.toString()+“|”+attrrecno.toString()+“|”+addressLineTwo+“|”+addressLineTwo+“|”+addressLineFour+“|”+“+city+“|”+“+country+“|”+“+success+“|”+String.valueOf(Thread.currentThread().getId());
写日志(logLine);
}
捕获(例外e)
{
e、 printStackTrace();
}
}
私有同步的void writeToLog(字符串行){
试一试{
fw.write(第+行“\r\n”);
fw.flush();
}
捕获(IOEX异常)
{
System.out.println(“写入日志文件时出错。”+ex.getMessage());
}
}
}
我不知道线程是否也多次调用updateRow方法,但我假设它们也在调用,这真的很糟糕


你知道为什么要这样做吗?

我认为ResultSet不是线程安全的。从代码中,您应该首先获取值,然后将值而不是rs传递到线程中。

看起来在
writeToLog()
中可能有多个线程,除非它已同步。您尝试过同步吗?很抱歉,我应该共享writeToLog()方法。我更新了我的问题,将其包括在内。它是同步的。谢谢……看起来你是对的。结果集不是线程安全的。既不是报表也不是准备好的报表。我可以创建一个新的ResultSet对象并将其分配给rs吗?或者我会因为通过引用传递而遇到问题吗?我不知道为什么必须通过结果
rs = ps.executeQuery();

while (rs.next()) {
    exec.execute(new UpdateMember(rs, conn, fileWriter));

    if (worksQueue.size() == blockingQueueSize) {
        //reach the maximum, stop refill
        for (;;) {
            Thread.yield();
            //wait until the size of queue reached the minimum  
            if (worksQueue.size() == 0) {
                //start refill
                break;
            }
        }
    }
}
public class UpdateMember implements Runnable {

    ResultSet rs;
    Connection conn;
    FileWriter fw;

    public UpdateMember(ResultSet rs, Connection conn, FileWriter fw) {
        this.rs = rs;
        this.conn = conn;
        this.fw = fw;
    }

    @Override
    public void run() {
        try {
            String regex = "((?<city>[a-zA-Z\\s\\.]+)\\s)?(?<provState>AB|ALB|Alta|alberta|BC|B\\.C\\.|British Columbia|LB|Labrador|MB|Man|Manitoba|N[BLTSU]|Nfld|NF|Newfoundland|NWT|Northwest Territories|Nova Scotia|New Brunswick|Nunavut|ON|ONT|Ontario|PE|PEI|Prince Edward Island|QC|PC|QUE|QU|Quebec|SK|Sask|Saskatchewan|YT|Yukon|Yukon Territories)(\\s(?<country>CA|CAN|CANADA))?$";
            Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

            BigDecimal memrecno = rs.getBigDecimal(2);
            String addressLineTwo = rs.getString(4);
            String addressLineThree = rs.getString(5);
            String addressLineFour = rs.getString(6);
            BigDecimal attrrecno = rs.getBigDecimal(9);

            String addressBeingParsed = "";
            String city = null;
            String province = null;
            String country = null;

            boolean usingAddressThree = false;
            boolean usingAddressFour = false;

            if (addressLineFour == null) {
                if (addressLineThree == null) {
                    city = "Unknown";
                }
                else
                {
                    addressBeingParsed = addressLineThree;
                    usingAddressThree = true;
                }
            }
            else
            {
                addressBeingParsed = addressLineFour;
                usingAddressFour = true;
            }

            if (usingAddressThree || usingAddressFour) {
                Matcher matcher = pattern.matcher(addressBeingParsed);

                // if matches are found
                if (matcher.matches()) {
                    city = matcher.group("city");
                    province = matcher.group("provState");
                    country = matcher.group("country");

                    if (city == null || city.isEmpty()) {
                        // cities are alpha characters and spaces only
                        String cityRegex = "(?<city>^[a-zA-Z\\s\\.]+$)";
                        Pattern cityPattern = Pattern.compile(cityRegex, Pattern.CASE_INSENSITIVE);

                        if (usingAddressFour && (addressLineThree != null) && !addressLineThree.isEmpty()) {
                            Matcher cityMatcher = cityPattern.matcher(addressLineThree);
                            if (cityMatcher.matches()) {
                                city = cityMatcher.group("city");
                            }
                            else
                            {
                                city = "Unknown";
                            }
                        }
                        else if (usingAddressThree && (addressLineTwo != null) && !addressLineTwo.isEmpty()) {
                            Matcher cityMatcher = cityPattern.matcher(addressLineTwo);
                            if (cityMatcher.matches()) {
                                city = cityMatcher.group("city");
                            }
                            else
                            {
                                city = "Unknown";
                            }
                        }
                        else
                        {
                            city = "Unknown";
                        }
                    }

                    if (province != null && !province.isEmpty()) {
                        province = createProvinceCode(province);
                    }
                }
                else
                {
                    city = "Unknown";
                }
            }

            // update attributes in database
            boolean success = updateRow(memrecno, attrrecno, city, province);

            String logLine = memrecno.toString() + "|" + attrrecno.toString() + "|" + addressLineTwo + "|" + addressLineThree + "|" + addressLineFour + "|" + city + "|" + province + "|" + country + "|" + success + "|" + String.valueOf(Thread.currentThread().getId());

            writeToLog(logLine);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private synchronized void writeToLog(String line) {
        try {
            fw.write(line + "\r\n");
            fw.flush();
        }
        catch (IOException ex)
        {
            System.out.println("Error writing to log file. " + ex.getMessage());
        }
    }
}