zoukankan      html  css  js  c++  java
  • 多线程读取,单线程写入

    场景: 应用中有一个IPList数组,用于屏蔽一些IP的访问,这个IP数组可以动态修改(写入)。

    我之前设计是这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    private String[] ipList;
     
    public boolean isDisallowIP(String ip)
    {
     
        if (ipList == null)
        {
            return true;
        }
        else
        {
            for (String theIP: ipList) {
                if (ip.startsWith(theIP)) {
                    return true;
                }
            }
            return false;
        }
    }

    //更新IP列表

    public void updateIPList()

    {

    String[] tempList = new String[...];

    ......

    ipList = tempList;

    }

    今天我在想,如果我刚刚添加一个新的IP到IPList中或从IPList数组中删除几个元素,而这个时候有多个线程同时在读取IPList会不会造成索引越界?

    我特意写了一段代码测试:

    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    package test;
     
    public class ThreadTest
    {
         
        private int list[];
         
        public ThreadTest()
        {
            list = new int[1024];
             
            for(int i=0;i<1024;i++)
            {
                list[i] = (int)(Math.random() * 10000);
            }
             
            for(int i=0;i<10;i++)
            {
                new Read().start();
            }
             
            for(int i=0;i<1;i++)
            {
                new Update().start();
            }
        }
         
        //多个读
        class Read extends Thread
        {
            public void run()
            {
                while(true)
                {
                    //for(int x : list) 生成的字节码反编译出来是竟是这样: (真是有点侥幸...)  不会抛出索引越界
                    /*
                    int ai[];
                    int j = (ai = list).length;
                    for(int i = 0; i < j; i++)
                    {
                        int x = ai[i];
                        System.out.println(x);
                    }
                    */
                    for(int x : list)
                    {
                        System.out.println(x);
                    }
                     
                     
                    /*
                    //int[] list = ThreadTest.this.list; //如果不加这行,下面就会抛出索引越界
                     
                    int size = list.length;
                    for(int i=0;i<size;i++)
                    {
                        //int x = list[i];
                         
                        System.out.println(list[i]);
                    }
                    */
                }          
            }
        }
         
        //单个修改
        class Update extends Thread
        {
            public void run()
            {
                while(true)
                {
                    int count = (int)(Math.random() * 1024);
                    int[] temp = new int[count];
                     
                    for(int i=0;i<count;i++)
                    {
                        temp[i] = (int)(Math.random() * 10000);
                    }
                     
                    list = temp;
                }
            }
        }
         
         
        public static void main(String[] args)
        {
            new ThreadTest();
        }
    }

    经过这段代码测试结果表明:单线程修改IPList,多线程读取IPList的时候,在读取的代码段,最好这样操作:

    String tempList = ipList; //其实想象在c语言中的指针,就非常好理解了。

    int count = tempList.length;

    for(int i=0;i<count;i++)

    {

        ...

    }

    这样就不会出现当动态修改数组时,出现访问时索引越界。

    2013-08-06

  • 相关阅读:
    python 中文文档地址总结
    清除celery 任务队列
    celery work logging 问题
    mysql 数据库 存储数据类型
    python 补0的方法
    lunix 命令积累
    python3 import Crypto 失败的解决办法 (AES对称加密使用 模块)
    从excel 获取内容 模块:xlrd
    api h5 sdk 接入的说明
    Excel 打开两个单独的页面
  • 原文地址:https://www.cnblogs.com/personnel/p/4584905.html
Copyright © 2011-2022 走看看