标准的Java 1.6 javax.xml.parsers.DocumentBuilder类是否安全?从多个线程并行调用parse()方法是否安全?
JavaDoc没有提到这个问题,但Java 1.4中同一类的JavaDoc明确表示它并不意味着并发; 所以我可以假设在1.6中它是?
原因是我在ExecutorService中运行了数百万个任务,每次调用DocumentBuilderFactory.newDocumentBuilder()似乎都很昂贵.
我最近一直在阅读Java Concurrency in Practice - 很棒的书.如果你认为你知道并发是如何工作的,但是大部分时间你都面对真正的问题,感觉SWAG是你能做的最多,那么本书肯定会对这个话题有所了解.当你尝试在线程之间共享数据时,有多少东西实际上会出错,这有点可怕.我想这让我对线程安全感觉有点疯狂.现在我担心的是,由于同步太多,我可能会遇到一些活动问题.这是一段代码来说明:
private final Hashtable<String, AtomicInteger> userSessions =
new Hashtable<String, AtomicInteger>();
public void registerUser(String userLogin) {
synchronized(userSessions) {
AtomicInteger sessionCount = userSessions.get(userLogin);
if (sessionCount != null) {
sessionCount.incrementAndGet();
} else {
userSessions.put(userLogin, new AtomicInteger(1));
}
}
}
public void unregisterUser(String userLogin) {
synchronized(userSessions) {
AtomicInteger sessionCount = userSessions.get(userLogin);
if (sessionCount != null) {
sessionCount.decrementAndGet();
}
}
}
public boolean isUserRegistered(String userLogin) {
synchronized(userSessions) {
AtomicInteger sessionCount = userSessions.get(userLogin);
if (sessionCount == null) {
return false; …Run Code Online (Sandbox Code Playgroud) 如果每个线程写入单独的单元格空间,是否需要在Java中同步对数组的写访问?
编辑:具体来说,数组是原始数组或不可变对象数组.防爆.int数组或String数组.
由于以下观察,我问这个问题
在高度多线程环境中的线程转储中获取此堆栈跟踪
"http-80-200" daemon prio=10 tid=0x00002aaab4981000 nid=0x7520 waiting \
for monitor entry [0x000000004fec7000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.security.SecureRandom.nextBytes(SecureRandom.java:433)
- waiting to lock <0x00000000c00da220> (a java.security.SecureRandom)
at java.util.UUID.randomUUID(UUID.java:162)
Run Code Online (Sandbox Code Playgroud)找到了这个链接
如果UUID不是线程安全的,请建议任何其他库(如果存在).
ObservableCollection为每个对它们执行的操作发出通知.首先,他们没有批量添加或删除调用,其次他们不是线程安全的.
这不会让他们变慢吗?我们有更快的选择吗?有人说ICollectionView缠得ObservableCollection很快?这种说法有多正确.
boost::posix_time::ptime parseDate(const std::string& format, const std::string& localDate)
{
std::istringstream is(localDate);
is.imbue(std::locale(is.getloc(), new boost::local_time::local_time_input_facet(format.c_str())));
boost::posix_time::ptime pt;
is >> pt;
if (pt == boost::posix_time::ptime())
{
throw std::runtime_error("Parse error");
}
return pt;
}
Run Code Online (Sandbox Code Playgroud)
此函数应采用日期和格式字符串和return boost::posix_time::ptime.
例如:2012:06:14 02:50:58和%Y:%m:%d %H:%M:%S.
但是,如果我在多线程程序中调用它,有时抛出异常,虽然format并且localDate是正确且可解析的(我对每次调用都使用相同的日期).我发现了一些关于std::stringstream/ std::locale线程问题但没有更新的东西(我正在使用gcc 4.6.3 64位).
这里有人有同样的问题:
使用Valgrind/drd测试过去几天,我发现我的代码中有很多部分会导致问题.例如,当调用一些提升日期时间转换函数时,我点击std :: locale(),这不是线程安全的.
更新的代码没有问题:
boost::posix_time::ptime parseDate(const std::string& format, const std::string& localDate)
{
std::istringstream is(localDate);
auto* facet = new boost::local_time::local_time_input_facet(format.c_str());
{
boost::unique_lock<boost::mutex> lock(globalLocaleMutex);
is.imbue(std::locale(is.getloc(), facet));
}
boost::posix_time::ptime …Run Code Online (Sandbox Code Playgroud) unique_ptr线程安全吗?以下代码是否无法两次打印相同的数字?
#include <memory>
#include <string>
#include <thread>
#include <cstdio>
using namespace std;
int main()
{
unique_ptr<int> work;
thread t1([&] {
while (true) {
const unique_ptr<int> localWork = move(work);
if (localWork)
printf("thread1: %d\n", *localWork);
this_thread::yield();
}
});
thread t2([&] {
while (true) {
const unique_ptr<int> localWork = move(work);
if (localWork)
printf("thread2: %d\n", *localWork);
this_thread::yield();
}
});
for (int i = 0; ; i++) {
work.reset(new int(i));
while (work)
this_thread::yield();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) 堆栈溢出.再一次,我在一个迫切需要的时候来找你,在疯狂的边缘岌岌可危地摇摇欲坠.这个问题 - 从标题中可以看出 - 是我在这里回答的其他几个问题的合并.
我有一个PyQt应用程序,我想将stdout和stderr流重新路由到我的GUI中的QTextEdit,没有延迟.
最初,我发现以下堆栈溢出答案: https ://stackoverflow.com/a/17145093/629404
这很有效,但有一点需要注意:如果在CPU处理相对较长的方法时多次更新stdout或stderr,则当主线程返回到应用程序循环时,所有更新都会同时显示.不幸的是,我有一些方法需要20秒才能完成(网络相关),因此应用程序变得无响应 - 并且QTextEdit不会更新 - 直到它们完成.
为了解决这个问题,我将所有GUI处理委托给主线程,并且我已经产生了第二个线程以处理更长的网络操作,使用pyqtSignals通知主线程工作何时完成并通过回来的结果.当我开始测试以这种方式编写的代码时,python解释器立刻开始崩溃而没有任何警告.
这是非常令人讨厌的地方:Python正在崩溃,因为 - 使用上面包含的链接中的类 - 我已经将sys.stdout/err流分配给QTextEdit小部件; PyQt小部件不能从除应用程序线程之外的任何线程修改,并且由于对stdout和stderr的更新来自我创建的辅助工作线程,因此它们违反了此规则.我已经注释掉了我重定向输出流的代码部分,果然,程序运行没有错误.
这让我回到原点,让我陷入困惑的境地; 假设我继续在主线程中处理GUI相关操作并处理辅助线程中的计算和更长时间的操作(我已经理解这是在用户触发事件时阻止应用程序阻塞的最佳方法),我该怎么办将Stdout和Stderr从两个线程重定向到QTextEdit小部件?上面链接中的类对于主线程来说效果很好,但是当更新来自第二个线程时,由于上述原因会杀死python.
Stringbuilder异步写入文件.此代码控制文件,将流写入其中并释放它.它处理来自异步操作的请求,这些请求可能随时进入.
在FilePath每类实例(所以锁组件,Object每个实例),但有潜在的冲突,因为这些类可以共享FilePaths.这种冲突以及来自类实例之外的所有其他类型将被处理重试.
这段代码是否适合其目的?有没有更好的方法来处理这个意味着更少(或没有)依赖捕获和重试机制?
另外,我如何避免捕获因其他原因而发生的异常.
public string Filepath { get; set; }
private Object locker = new Object();
public async Task WriteToFile(StringBuilder text)
{
int timeOut = 100;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (true)
{
try
{
//Wait for resource to be free
lock (locker)
{
using (FileStream file = new FileStream(Filepath, FileMode.Append, FileAccess.Write, FileShare.Read))
using (StreamWriter writer = new StreamWriter(file, Encoding.Unicode))
{
writer.Write(text.ToString());
}
}
break;
}
catch
{
//File not …Run Code Online (Sandbox Code Playgroud) 在boost的实现中shared_ptr,它使用宽松的内存排序来增加其引用计数.这似乎是安全的,因为减量使用获取/释放来确保在释放内存之前线程可以看到任何先前的减量.这种方法似乎是正确的,并出现在Herb Sutters 谈论原子论
在libc ++中,实现使用全内存屏障
template <class T>
inline T
increment(T& t) _NOEXCEPT
{
return __sync_add_and_fetch(&t, 1);
}
template <class T>
inline T
decrement(T& t) _NOEXCEPT
{
return __sync_add_and_fetch(&t, -1);
}
} // name
Run Code Online (Sandbox Code Playgroud)
这个决定有理由吗?它们之间是否有任何性能或安全差异?
thread-safety ×10
java ×4
c++ ×3
boost ×2
arrays ×1
c# ×1
c++11 ×1
concurrency ×1
date-parsing ×1
filesystems ×1
gcc4 ×1
libc++ ×1
pyqt ×1
python ×1
shared-ptr ×1
stdout ×1
unique-ptr ×1
wpf ×1