zoukankan      html  css  js  c++  java
  • Android中Sqlite数据库多线程并发问题

    最近在做一个Android项目, 为了改善用户体验,把原先必须让用户“等待”的过程改成在新线程中异步执行。但是这样做遇到了多个线程同时需要写Sqlite数据库,导致操作数据库失败。

    本人对Java并不熟悉,只接触了2个多月(纯粹为了Android项目, 才开始接触JAVA), 在网上搜了一下, 发现JAVA在线程同步方面提供的功能相对于C#真少,只找到synchronized关键字, 而且还不提供timeout机制, 不过经过测试, 至少解决了目前的需求。

    问题需求:

    1. Android中, 对Sqlite数据库操作, 需要自己实现一个继承自SQLiteOpenHelper的类

    2. 实现类中, 对数据库read操作不需要同步(提高效率)

    3. 实现类中, 所有对数据库写操作, 必须要同步

    解决方法:

    定义一个private final static byte[] _writeLock = new byte[0]; 作为写锁

    static  保证多个实例之间, 使用的是同一个对象(同一把锁)

    final 保证锁对象不会被修改

    测试代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    package com.yushiro;
     
     
    public class multiThreadTest {
     
        private final static byte[] _writeLock = new byte[0];
        private static int _syncInt = 0;
        public void Method1(){
            synchronized (_writeLock) {
                StringBuffer sb = new StringBuffer();
                sb.append(Thread.currentThread().getName());
                sb.append(" Method1 ");
                sb.append(_syncInt);
                _syncInt++;
                sb.append(" --> ");
                sb.append(_syncInt);
                System.out.println(sb.toString());
            }
        }
         
        public void Method2(){
            synchronized (_writeLock) {
                StringBuffer sb = new StringBuffer();
                sb.append(Thread.currentThread().getName());
                sb.append(" Method2 ");
                sb.append(_syncInt);
                _syncInt++;
                sb.append(" --> ");
                sb.append(_syncInt);
                System.out.println(sb.toString());      }
        }
         
        public void Method3(){
            synchronized (_writeLock) {
                this.Method1();
                this.Method2();
                }
        }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    package com.yushiro;
     
     
    public class MainTest {
     
         
        public static void main(String[] args) {
             
            Thread t2= new Thread1();
            Thread t1= new Thread2();
            Thread t3 = new Thread3();
            t1.start();
            t2.start();
            t3.start();
        }
     
        private static class Thread2 extends Thread {
            public void run() {
                multiThreadTest tmp = new multiThreadTest();
                while(true) {
                     
                     
                    try {
                        Thread.sleep(30000);
                        tmp.Method1();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                     
                    //System.out.println(y);
                }
            }
        }
         
        private static class Thread1 extends Thread {
            public void run() {
                multiThreadTest tmp = new multiThreadTest();
                while(true) {
                     
                     
                    try {
                        Thread.sleep(100);
                        tmp.Method2();
                        Thread.sleep(100);
                        tmp.Method1();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                     
                    //System.out.println(y);
                }
            }
        }
        private static class Thread3 extends Thread {
            public void run() {
                multiThreadTest tmp = new multiThreadTest();
                while(true) {
                     
                     
                    try {
                        Thread.sleep(100);
                        tmp.Method3();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                     
                    //System.out.println(y);
                }
            }
        }
     
    }

    Method3()是为了测试自旋锁

    参考:

    Java同步机制总结--synchronized(http://leo-faith.iteye.com/blog/177779)

  • 相关阅读:
    (转)Linux端口nmap和netstat命令
    (转)Linux下增加交换分区的大小
    (转)centos7安装telnet服务
    (转)VmWare下安装CentOS7图文安装教程
    (转)Linux系统安装时分区的选择
    (转)硬盘分区备忘(主分区,扩展分区和逻辑分区)以及Linux硬盘分区工具parted 介绍
    (转).tar.gz文件和.rpm文件的区别
    (转)Linux(Centos)之安装Java JDK及注意事项
    ibatis中integer类型
    ibatis时间比较大小
  • 原文地址:https://www.cnblogs.com/wangfeng520/p/6845589.html
Copyright © 2011-2022 走看看