2013-04-30 3 views
5

onCreate() 내 주요 활동의 방법으로 dbManager의 생성자를 호출하는데, 나는 SQLiteOpenHelper의 인스턴스를 생성하는 open 함수를 호출하고 그 대신 getWritableDatabase()을 호출합니다. UIThread 내에서 레코드를 데이터베이스에 추가하고 해당 레코드를 ArrayList에 저장합니다. 다른 두 개의 스레드는 ArrayList가 수행 할 작업을 확인하고 목록과 데이터베이스를 업데이트합니다. 이제 UI에 버튼을 추가하여 AsyncTask을 사용하여 데이터베이스 및 목록 레코드를 모두 삭제하려고합니다. SqliteOpenHelper 개체가 하나의 데이터베이스 연결에서 보유하고 있음을 읽었습니다. 따라서 하나의 도우미 인스턴스가있는 경우 단 하나의 db 연결 만 있습니다. 이 연결은 여러 스레드에서 사용할 수 있으며 SqliteDatabase 개체는 java 잠금을 사용하여 액세스를 serialize 할 수 있습니다. 그래서 데이터베이스에 쓰는 쓰레드가 여러 개인 경우, 쓰레드는 이전 작업이 끝날 때까지 기다릴 것입니다.
두 스레드 중 하나가 더 이상 존재하지 않는 레코드를 편집하려고 시도하지 않아야하므로 새 기능을 추가하면 (모두 제거) 문제가 발생할 수 있습니다. 목표를 어떻게 달성 할 수 있습니까? 감사.안드로이드 : SQLite 데이터베이스에 쓰는 다중 쓰레드

+0

소비자 및 생산자 패턴을 구현해야합니다. 요청 큐를 작성하고 데이터베이스에 병렬로 쓰지 않아야합니다. – IamStalker

+0

은 편집을 구현하는 방법에 따라 다르지만 SQL 업데이트는 n을 반환합니다. 여기서 n은 수정 된 항목의 수이며, where 절과 일치하는 레코드가 없으면 완전히 0이 될 수 있습니다. – njzk2

+0

1) UI 스레드에서 DB 작업을해서는 안됩니다. 2) ArrayList 읽기/쓰기 스레드를 하나만 갖습니다. @IamStalker 왜 DB에 병렬로 쓰지 않습니까? – m0skit0

답변

4

databese :

는만큼 당신이 하나의 도우미를 사용할 때, 당신은 아무것도 할 필요없이 스레드로부터 안전합니다.
멀티 스레드 앱에서는 도우미 작성시에만 synchronized이 필요합니다. 크리티컬 섹션 (두 개 이상의 원자 연산)을 정의하려면 transacion을 사용할 수 있습니다.
getWritableDatabase()close(false) 각 전화 :

public void doSomething() { 
    SQLiteDatabase tdb = getWritableDatabase(); 
    dbInstance.writeSomething(tdb, 1); 
    close(false); 
} 

이 방법으로는 여러 개의 스레드가 읽고 아무 ​​문제없이 데이터베이스에 기록합니다.

당신의 응용 프로그램 로직 :

사용 메모리는 객체의 상태를 추적, 오직 스토리지로 데이터베이스를 사용합니다. 따라서 한 스레드가 데이터베이스에서 행을 삭제하면 메모리에서 객체를 즉시 업데이트하고 이에 따라 UI를 처리 할 수 ​​있습니다.
데이터가 매우 큰 경우 메모리에 유지할 수있는 것보다 더러운 행 id가 SparseArray 인 경우에만 id.
여기에서 일부 작업을 동기화하는 것이 유용 할 수 있습니다.

+0

당신의 코드에서 동기화가 어디에서 사용됩니까? – IamStalker

+0

데이터베이스 도우미가 데이터베이스 무결성을 유지하는 데 필요한 모든 동기화를 수행하고 있습니다. 또한 응용 프로그램 논리에서 db와 관련이 없으므로 개발자는 비즈니스 로직 무결성을 유지하기 위해 코드의 중요한 섹션을 동기화해야 할 수도 있습니다. – auval

+0

그런 한계는 없지만, 백 개의 스레드가 동일한 DB에 문제없이 읽고 쓸 수 있습니다. 헬퍼 한 명 사용. 이것은 멀티 스레드 응용 프로그램을 작성할 때 문제가있는 곳이 아닌 * *입니다. – auval

0

그래서 데이터베이스에 쓰는 스레드가 여러 개인 경우 스레드는 이전 작업이 완료 될 때까지 대기 할 것입니다. ?

그렇게하지 않아도됩니다. 자세한 내용은 this을 참조하십시오. 어쨌든 이것은 DB 엔진에 달려 있으며 투명해야합니다.

나는 두 개의 스레드 중 하나가 더 이상 존재하지 기록을 편집하려고 할 수 있다는 것을 방지하기 때문에, 을 문제를 만들 수있는 새로운 기능 (모두 제거)을 추가. 목표를 어떻게 달성 할 수 있습니까?

DB를 하나만 업데이트하면됩니다. ArrayList은 스레드로부터 안전하지 않으므로 다른 스레드는 ArrayList 만 수정하므로 Collections#synchronizedList()을 사용해보십시오.

관련 문제