我们AsyncTasks用来访问数据库表和游标.
不幸的是,我们偶尔会看到有关数据库被锁定的例外情况.
E/SQLiteOpenHelper(15963): Couldn't open iviewnews.db for writing (will try read-only):
E/SQLiteOpenHelper(15963): android.database.sqlite.SQLiteException: database is locked
E/SQLiteOpenHelper(15963): at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
E/SQLiteOpenHelper(15963): at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1637)
E/SQLiteOpenHelper(15963): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1587)
E/SQLiteOpenHelper(15963): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:638)
E/SQLiteOpenHelper(15963): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:659)
E/SQLiteOpenHelper(15963): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:652)
E/SQLiteOpenHelper(15963): at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:482)
E/SQLiteOpenHelper(15963): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)
E/SQLiteOpenHelper(15963): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
E/SQLiteOpenHelper(15963): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158)
E/SQLiteOpenHelper(15963): at com.iview.android.widget.IViewNewsTopStoryWidget.initData(IViewNewsTopStoryWidget.java:73)
E/SQLiteOpenHelper(15963): at com.iview.android.widget.IViewNewsTopStoryWidget.updateNewsWidgets(IViewNewsTopStoryWidget.java:121)
E/SQLiteOpenHelper(15963): at com.iview.android.async.GetNewsTask.doInBackground(GetNewsTask.java:338)
E/SQLiteOpenHelper(15963): at com.iview.android.async.GetNewsTask.doInBackground(GetNewsTask.java:1)
E/SQLiteOpenHelper(15963): at android.os.AsyncTask$2.call(AsyncTask.java:185)
E/SQLiteOpenHelper(15963): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
E/SQLiteOpenHelper(15963): at java.util.concurrent.FutureTask.run(FutureTask.java:122)
E/SQLiteOpenHelper(15963): at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
E/SQLiteOpenHelper(15963): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
E/SQLiteOpenHelper(15963): at java.lang.Thread.run(Thread.java:1060)
Run Code Online (Sandbox Code Playgroud)
有没有人有一个代码的一般例子,它从一个读取的不同线程写入数据库,我们如何确保线程安全. …
我刚读完"Nutshell中的C#4.0"(O'Reilly),我认为这对于愿意转向C#的程序员来说是一本好书,但它让我感到疑惑.我的问题是using声明的定义.根据这本书(第138页),
using (StreamReader reader = File.OpenText("file.txt")) {
...
}
Run Code Online (Sandbox Code Playgroud)
恰好相当于:
StreamReader reader = File.OpenText("file.txt");
try {
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
Run Code Online (Sandbox Code Playgroud)
但是,假设这是真的,并且此代码在单独的线程中执行.此线程现在已中止thread.Abort(),因此ThreadAbortException抛出a并假设线程正好在初始化读取器之后和输入try..finally子句之前.这意味着读者不会被处置!
一种可能的解决方案是以这种方式编码:
StreamReader reader = null;
try {
reader = File.OpenText("file.txt");
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
Run Code Online (Sandbox Code Playgroud)
这将是中止安全的.
现在我的问题:
using声明是不是中止安全还是错误,它的行为与我的第二个解决方案相似?using等同于第一方案(不放弃安全的),为什么它检查null的finally?ThreadAbortException可以在托管代码中的任何位置抛出.但也许有例外,第一个变种毕竟是中止安全的?编辑:我知道使用thread.Abort()不被认为是好习惯.我的兴趣是纯粹的理论:如何在using声明中表现究竟?
可能有人告诉我是否可以从一个@synchronized街区内返回?
例如:
- (id)methodThatReturnsSomething:(BOOL)bDoIt
{
@synchronized(self) {
if(!bDoIt) return nil;
...
}
}
Run Code Online (Sandbox Code Playgroud)
或者我应该先解锁块(使用NSLock代替)?
我试图从一个线程读取一个combobox.Text而不是它创建的线程,但我收到错误:
System.Windows.Forms.dll中发生了未处理的"System.InvalidOperationException"类型异常
附加信息:跨线程操作无效:控制'levelsComboBox'从其创建的线程以外的线程访问.
我之前使用过.Invoke但只是设置属性,我怎么用它来读取combobox.Text?因为.Invoke返回void,我需要一个字符串.或者没有Invoke有另一种方法吗?
我在IronPython中定义了一个无副作用(纯)lambda表达式,并将其分配给C#委托.当从多个线程同时调用委托时,我得到类型为AccessViolationException,NullReferenceException和FatalEngineExecutionError的异常.
错误的发生是非确定性的,并且它主要需要数百万次迭代来激发它,这对我说"竞争条件".我怎么能避免呢?
只有在使用x64(x86不崩溃)并且在调试器之外运行进程时才会引发异常.测试系统是Windows 7,.NET Framework 4.0和IronPython 2.7.1上的Core I7(8个线程).
这是产生错误的最小代码:
var engine = Python.CreateEngine();
double a = 1.0;
double b = 2.0;
while (true)
{
Func<double, double, double> calculate = engine.Execute("lambda a,b : a+b");
System.Threading.Tasks.Parallel.For(0, 1000, _ =>
{
for (int i = 0; i < 1000; i++) { calculate(a,b); }
});
Console.Write(".");
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
检测到FatalExecutionEngineError
消息:运行时遇到致命错误.错误的地址是0xf807829e,位于线程0x3da0上.错误代码是0xc0000005.此错误可能是CLR中的错误,也可能是用户代码的不安全或不可验证部分中的错误.此错误的常见来源包括COM-interop或PInvoke的用户编组错误,这可能会破坏堆栈.
更新:即使引擎声明为线程本地,它会在一段时间后崩溃:
var calculate = new ThreadLocal<Func<double, double, double>>(() => Python.CreateEngine().Execute("lambda a,b : a+b"));
Run Code Online (Sandbox Code Playgroud) 我有2个ASyncTasks,一个从httpPost检索一个值,另一个更新UI的一些元素(包括listview).问题是,由于两个ASyncTasks共享相同的后台线程,如果网络操作首先启动并且运行缓慢(由于网络连接不良).其他背景线程花费太多时间使应用程序不负责任.
由于两个ASyncTasks都是独立的,因此等待另一个非常愚蠢.这将是更合乎逻辑的asynctasks不同的类使用不同的线程,我错了吗?
阅读ASyncTask文档.谈谈使用 executeOnExecutor(),但是如何在低于11的API级别解决这个问题呢?
这是一个重现"问题"的小例子
new Task1().execute();
new Task2().execute();
Run Code Online (Sandbox Code Playgroud)
同
public class Task1 extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
GLog.e("doInBackground start 1");
SystemClock.sleep(9000);
GLog.e("doInBackground end 1");
return null;
}
@Override
protected void onPreExecute() {
GLog.e("onPreExecute 1");
super.onPreExecute();
}
@Override
protected void onPostExecute(Void result) {
GLog.e("onPostExecute 1");
super.onPostExecute(result);
}
}
public class Task2 extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
GLog.e("onPreExecute 2");
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) { …Run Code Online (Sandbox Code Playgroud) 让我们说我想让这段代码线程安全:
- (void) addThing:(id)thing { // Can be called from different threads
[_myArray addObject:thing];
}
Run Code Online (Sandbox Code Playgroud)
GCD似乎是实现这一目标的首选方式:
- (void) addThing:(id)thing {
dispatch_sync(_myQueue, ^{ // _myQueue is serial.
[_myArray addObject:thing];
});
}
Run Code Online (Sandbox Code Playgroud)
与传统方法相比,它有什么优势?
- (void) addThing:(id)thing {
@synchronized(_myArray) {
[_myArray addObject:thing];
}
}
Run Code Online (Sandbox Code Playgroud) 我知道volatile允许可见性,AtomicInteger允许原子性.所以,如果我使用volatile AtomicInteger,是否意味着我不必再使用任何同步机制?
例如.
class A {
private volatile AtomicInteger count;
void someMethod(){
// do something
if(count.get() < 10) {
count.incrementAndGet();
}
}
Run Code Online (Sandbox Code Playgroud)
这线程安全吗?
我用768mb ram运行centos 5.5.我一直server reached MaxClients setting, consider raising the MaxClients setting在日志中,apache运行真的很慢.当我看到仙人掌图时,它显示服务器甚至没有使用所有资源..这是当前配置
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 10
ServerLimit 1024
MaxClients 768
MaxRequestsPerChild 4000
</IfModule>
<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
free -m
total used free shared buffers cached
Mem: 768 352 415 0 0 37
-/+ buffers/cache: 315 452
Swap: 0 0 0
top - 11:03:54 up 41 days, 11:53, 1 user, load average: 0.05, 0.03, 0.00 …Run Code Online (Sandbox Code Playgroud) 我们知道,默认情况下迭代并发集合不是线程安全的,所以不能使用:
Set<E> set = Collections.synchronizedSet(new HashSet<>());
//fill with data
for (E e : set) {
process(e);
}
Run Code Online (Sandbox Code Playgroud)
这是因为在迭代期间可能会添加数据,因为没有排他锁set.
这在javadoc中描述Collections.synchronizedSet:
public static Set synchronizedSet(Set s)
返回由指定集支持的同步(线程安全)集.为了保证串行访问,必须通过返回的集完成对后备集的所有访问.
当迭代它时,用户必须手动同步返回的集合:
Set s = Collections.synchronizedSet(new HashSet());
...
synchronized (s) { Iterator i = s.iterator(); // Must be in the synchronized block while (i.hasNext()) foo(i.next()); }不遵循此建议可能会导致非确定性行为.
然而,这并不适用于Set.forEach,它继承了默认的方法forEach从Iterable.forEach.
现在我查看了源代码,在这里我们可以看到我们有以下结构:
Collections.synchronizedSet().我们得到一个:
public static <T> Set<T> synchronizedSet(Set<T> s) {
return new SynchronizedSet<>(s); …Run Code Online (Sandbox Code Playgroud)thread-safety ×10
c# ×3
android ×2
java ×2
objective-c ×2
abort ×1
apache ×1
atomic ×1
cacti ×1
collections ×1
invoke ×1
ios ×1
ironpython ×1
java-8 ×1
lambda ×1
locking ×1
performance ×1
sqlite ×1
synchronized ×1
volatile ×1