我有一个同步函数,它是从另一个函数的循环中在一个新线程中启动的,并且有许多调用它。所以我有:
foo(){
new SwingWorker() {
@Override
public void doInBackground() {
sync_foo();
}
}.execute();
} catch (IOException e) {
log.error("", e);
}
}
sync_foo
定义为:
private synchronized void sync_foo() {
}
我在sync_foo
中放了一些调试行来检查它是否按预期工作。所以我有:
private synchronized void sync_foo() {
final Logger log = Logger.getLogger(getClass());
log.info("start");
...
log.info("finish");
}
这里的记录器是Log4J,我理解它确实是线程安全的。我注意到在日志文件中我有时会有两个“开始”。所以我在末尾log.info("still alive")
附近添加了另一行,并继续靠近log.info("start");
,看看我是否曾停止获得双starts
并始终在still alive
之间获得log.info("start");
两个,但我还是得到它,最后我把它放在private synchronized void sync_foo() {
final Logger log = Logger.getLogger(getClass());
log.info("start");
log.info("still alive");
...
log.info("finish");
}
的下一行:
start
start
但是时不时地,我仍然得到:
sync_foo()
我发现非常令人费解。似乎该方法被某种程度上打断了,但我无法理解。我应该补充说foo()
仅从Dim sessionOptions As New WinSCP.SessionOptions With { ... initialize your ftp parameters here ... }
Using session As WinSCP.Session = New WinSCP.Session
session.Open(sessionOptions)
Dim fileInfos As WinSCP.RemoteDirectoryInfo = session.ListDirectory(ftpFolder)
For Each ftpFile As WinSCP.RemoteFileInfo In fileInfos.Files
' Here you get the file date:
Dim fileDate As Date = ftpFile.LastWriteTime
Next
End Using
调用,我没有收到任何异常或错误。
所以问题是:
一般来说,方法被自身中断的可能原因是什么?
我知道Swing worker可能有自己的处理线程执行的方法。我上面使用的SwingWorker实际上已被覆盖,并且在here中被定义。此扩展中是否有任何内容可以忽略相关的例外情况?
答案 0 :(得分:2)
同步取决于共享锁定,因此如果您看到多个线程正在调用同时同步的内容的行为,则意味着它们不使用相同的锁定。听起来像是在不同的对象上调用sync_foo。在方法上使用synchronized
意味着对象实例上的监视器是由想要输入方法的线程获取的,因此如果在不同的对象上调用该方法,则没有共享锁定且没有任何停止线程从一个对象上输入方法而另一个线程在另一个对象上执行该方法。
您可以像这样制作类级锁:
public static final Object LOCK = new Object();
并将您的方法更改为
private void sync_foo() {
synchronized(LOCK) {
final Logger log = Logger.getLogger(getClass());
log.info("start");
log.info("still alive");
...
log.info("finish");
}
}
所以调用sync_foo的所有对象都将使用相同的锁,无论它被调用的是什么实例。