标签: thread-safety

Android线程和数据库锁定

我们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)

有没有人有一个代码的一般例子,它从一个读取的不同线程写入数据库,我们如何确保线程安全. …

sqlite android locking thread-safety android-asynctask

28
推荐指数
4
解决办法
6万
查看次数

C#的使用语句是否中止?

我刚读完"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)

这将是中止安全的.

现在我的问题:

  1. 这本书的作者是否正确,using声明是不是中止安全还是错误,它的行为与我的第二个解决方案相似?
  2. 如果using等同于第一方案(不放弃安全的),为什么它检查nullfinally
  3. 根据该书(第856页),ThreadAbortException可以在托管代码中的任何位置抛出.但也许有例外,第一个变种毕竟是中止安全的?

编辑:我知道使用thread.Abort()不被认为是好习惯.我的兴趣是纯粹的理论:如何在using声明中表现究竟

c# multithreading using-statement thread-safety abort

28
推荐指数
3
解决办法
3224
查看次数

从objective-c中的@synchronized块内部返回

可能有人告诉我是否可以从一个@synchronized街区内返回?

例如:

    - (id)methodThatReturnsSomething:(BOOL)bDoIt
    {
        @synchronized(self) {      

             if(!bDoIt) return nil;
             ...
        }
    }
Run Code Online (Sandbox Code Playgroud)

或者我应该先解锁块(使用NSLock代替)?

objective-c synchronized thread-safety

28
推荐指数
1
解决办法
3346
查看次数

如何从除创建它之外的线程读取组合框?

我试图从一个线程读取一个combobox.Text而不是它创建的线程,但我收到错误:

System.Windows.Forms.dll中发生了未处理的"System.InvalidOperationException"类型异常

附加信息:跨线程操作无效:控制'levelsComboBox'从其创建的线程以外的线程访问.

我之前使用过.Invoke但只是设置属性,我怎么用它来读取combobox.Text?因为.Invoke返回void,我需要一个字符串.或者没有Invoke有另一种方法吗?

c# multithreading invoke thread-safety

28
推荐指数
3
解决办法
3万
查看次数

为什么从C#调用Python lambda表达式不是线程安全的?

我在IronPython中定义了一个无副作用(纯)lambda表达式,并将其分配给C#委托.当从多个线程同时调用委托时,我得到类型为AccessViolationException,NullReferenceExceptionFatalEngineExecutionError的异常.

错误的发生是非确定性的,并且它主要需要数百万次迭代来激发它,这对我说"竞争条件".我怎么能避免呢?

只有在使用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)

c# lambda ironpython thread-safety

28
推荐指数
1
解决办法
1032
查看次数

ASyncTasks阻止其他人

我有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)

multithreading android thread-safety android-asynctask

28
推荐指数
2
解决办法
7647
查看次数

dispatch_sync比@synchronized有什么优势?

让我们说我想让这段代码线程安全:

- (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)

multithreading objective-c thread-safety ios

28
推荐指数
1
解决办法
8816
查看次数

AtomicInteger和volatile

我知道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)

这线程安全吗?

java multithreading atomic volatile thread-safety

27
推荐指数
2
解决办法
2万
查看次数

apache服务器达到了MaxClients设置,请考虑提高MaxClients设置

我用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)

apache performance thread-safety cacti

27
推荐指数
1
解决办法
12万
查看次数

通过Collections.synchronizedSet(...).forEach()的迭代是否保证是线程安全的?

我们知道,默认情况下迭代并发集合不是线程安全的,所以不能使用:

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,它继承了默认的方法forEachIterable.forEach.

现在我查看了源代码,在这里我们可以看到我们有以下结构:

  1. 我们要求一个Collections.synchronizedSet().
  2. 我们得到一个:

    public static <T> Set<T> synchronizedSet(Set<T> s) {
        return new SynchronizedSet<>(s); …
    Run Code Online (Sandbox Code Playgroud)

java collections thread-safety java-8

27
推荐指数
2
解决办法
4460
查看次数