并行执行:如何在同步方法执行完成后使用Synchronized方法更新Excel WorkBook?

时间:2017-03-20 10:04:15

标签: java multithreading synchronization

我在类中编写了一个非静态同步方法,以避免多个线程同时更新Excel工作簿。例如,ID#9和#10的线程正在尝试更新Excel,期望Thread#9应该完成synchronized方法的操作,然后Thread#10应该能够调用我们没有发生的方法。以下是代码段。

public synchronized boolean put(String parameterName, String parameterValue) {
    try {
        System.out.println("Start Time:= " + Thread.currentThread().getId() + " :: " + LocalDateTime.now().toString());
        updateData(data.get("XLFileName"), data.get("XLSheetName"), parameterName, parameterValue, data.get("TestCaseID"), data.get("Iteration"));
        System.out.println("End Time:= " + Thread.currentThread().getId() + " :: " + LocalDateTime.now().toString());
        return true;
    } catch (FilloException flex) {
        flex.printStackTrace();
        // extentTest.log(LogStatus.FATAL, "A", flex.getMessage());
        return false;
    }
}

public void updateData(String XLFileName, String XLSheet, String parameterName, String parameterValue, String testCaseID, String iteration) throws FilloException {
    Fillo fillo = new Fillo();
    Connection connection = fillo.getConnection(XLFileName);
    String strQuery = "Update " + XLSheet + " Set " + parameterName + "='" + parameterValue + "' where TestCaseID = '" + testCaseID + "' and Iteration = '" + iteration + "'";
    connection.executeUpdate(strQuery);
    connection.close();

    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
Current Output:

Start Time:= 10 :: 2017-03-20T15:03:31.041
1 row(s) affected
Start Time:= 9 :: 2017-03-20T15:03:31.619
1 row(s) affected
End Time:= 10 :: 2017-03-20T15:03:41.201
End Time:= 9 :: 2017-03-20T15:03:41.675

Expected Output:

Start Time:= 10 :: 2017-03-20T15:03:31.041
1 row(s) affected
End Time:= 10 :: 2017-03-20T15:03:41.201
Start Time:= 9 :: 2017-03-20T15:03:31.619
1 row(s) affected
End Time:= 9 :: 2017-03-20T15:03:41.675

也尝试使用synchronized块。

2 个答案:

答案 0 :(得分:1)

你可以尝试使用带锁的同步块,如下所示。

public synchronized boolean put(String parameterName, String parameterValue) {
    synchronized (DataBook.class) {
        try {
            System.out.println("Start Time:= " + Thread.currentThread().getId() + " :: " + LocalDateTime.now().toString());
            updateData(data.get("XLFileName"), data.get("XLSheetName"), parameterName, parameterValue, data.get("TestCaseID"), data.get("Iteration"));
            System.out.println("End Time:= " + Thread.currentThread().getId() + " :: "  + LocalDateTime.now().toString());
            return true;

        } catch (FilloException flex) {
            flex.printStackTrace();
            return false;
        }
    }
}

答案 1 :(得分:0)

由于这不是静态的,因此这里使用的锁是intrinsic lock,即每个对象锁定。这意味着每个线程都有一个锁,因此每个线程都有权执行自己的put方法,从而实现您观察到的输出。

我建议获得所需的输出是将此方法设置为静态,以便锁定与类关联,并且一次只能有一个Thread访问它,为您提供预期的输出(或差不多,线程9可以比线程10更快地启动:

public static synchronized boolean put(String parameterName, String parameterValue)