多线程读取,单线程写入

场景: 应用中有一个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

时间: 2024-08-07 00:13:31

多线程读取,单线程写入的相关文章

Java多线程读取大文件

前言 今天是五一假期第一天,按理应该是快乐玩耍的日子,但是作为一个北漂到京师的开发人员,实在难想出去那玩耍.好玩的地方比较远,近处又感觉没意思.于是乎,闲着写篇文章,总结下昨天写的程序吧. 昨天下午朋友跟我聊起,他说有个需求,需要把上G的txt文件读取写入到数据库.用普通的io结果自然是OOM了,所以果断用NIO技术.为了提高速度,自然还得用上多线程技术. 接下来就介绍一下实现思路以及相关的知识点. 内容 一.对文件分区 为了充分利用多线程读取,就需要把文件划分成多个区域,供每个线程读取.那么就

读取和写入Cookies

#region 读取或写入cookie 2 /// <summary> 3 /// 写cookie值 4 /// </summary> 5 /// <param name="strName">名称</param> 6 /// <param name="strValue">值</param> 7 public static void WriteCookie(string strName, stri

Java 读取、写入文件——解决乱码问题

读取文件流时,经常会遇到乱码的现象,造成乱码的原因当然不可能是一个,这里主要介绍因为文件编码格式而导致的乱码的问题.首先,明确一点,文本文件与二进制文件的概念与差异. 文本文件是基于字符编码的文件,常见的编码有ASCII编码,UNICODE编码.ANSI编码等等.二进制文件是基于值编码的文件,你可以根据具体应用,指定某个值是什么意思(这样一个过程,可以看作是自定义编码.) 因此可以看出文本文件基本上是定长编码的(也有非定长的编码如UTF-8).而二进制文件可看成是变长编码的,因为是值编码嘛,多少

如何通过SerialPort读取和写入设备COM端口数据

SerialPort类用于控制串行端口文件资源.提供同步 I/O 和事件驱动的 I/O.对管脚和中断状态的访问以及对串行驱动程序属性的访问.另外,SerialPort的功能可以包装在内部 Stream 对象中,可通过 BaseStream 属性访问,并且可以传递给包装或使用流的类. 下面本文将如何通过实现COM端口配置.SerialPort调用配置打开端口.对设备端口进行读取操作. 1.        实现COM端口配置 COM端口主要配置有:COM端口名称.波特率.数据位数.停止位.奇偶校验及

文本文件从磁盘读取、写入

本文转自CSDN博客:http://blog.csdn.net/anchenyanyue/article/details/7666370 1 using System; 2 using System.Text; 3 using System.IO; 4 5 namespace XXXX.Common 6 { 7 /// <summary> 8 /// 文本文件从磁盘读取.写入 9 /// </summary> 10 public class FileHelper 11 { 12 1

CSharp文件读取与写入入门图解

C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序设计语言.并定于在微软职业开发者论坛(PDC)上登台亮相.C#是微软公司研究员Anders Hejlsberg的最新成果.C#看起来与Java有着惊人的相似:它包括了诸如单一继承.接口.与Java几乎同样的语法和编译成中间代码再运行的过程.但是C#与Java有着明显的不同,它借鉴了Delphi的一个特点,与COM(组件对象模型)是直接集成的,而且它是微软公司 .NET windows网络框架的主角. 用c#来读取

SQL SERVER 2012 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 (System.Data)

标题: 连接到服务器------------------------------无法连接到 192.168.1.253.------------------------------其他信息:尝试读取或写入受保护的内存.这通常指示其他内存已损坏. (System.Data)------------------------------按钮:确定------------------------------管理员身份运行 cmd -> netsh winsock reset***************

多线程和单线程的执行效率问题

一提到多线程一般大家的第一感觉就是可以提升程序性能,在实际的操作中往往遇到性能的问题,都尝试使用多线程来解决问题,但多线程程序并不是在任何情况下都能提升效率,在一些情况下恰恰相反,反而会降低程序的性能.这里给出两个简单的例子来说明下: 程序1: 1 import threading 2 from time import ctime 3 4 class MyThread(threading.Thread): 5 def __init__(self, func, args, name): 6 thr

python多线程读取同一个文件

多线程读取同一个文件,要求不能重复,不能遗漏. 最开始尝试了一种方法(后来实践证明是无效的) 主线程分配给每个读线程需要读取文件中哪些行, 比如线程1读取1-10行,线程2读取11-30行. 然后每个线程通过readline()来读取,读到的行如果不属于本线程的范围,则continue跳过. 实践证明,这若干个线程并没有按照我们期望来读. 我的猜想是,通过open来打开一个文件,多个线程返回的是同一个句柄, 或者一个文件的文件指针只有一个. 经过网上搜索和实践,总结出有以下方法支持多线程读取同一