如题   现有一个 arraylist 里面有 1000 行数据 ,现在要用 10 个去处理这些操作, arraylist 每被取一次就删掉被取的那个,如:  线程 a 从 arraylist 里取了一个值, 然后 arraylist remove掉那个, arraylist 去处理刚才取到的值, 线程b去取值,然后执行与线程a 相同的操作,线程 c 也一样,  当 线程a 刚刚那个直处理完毕后又去 arraylist 里取一个再处理,
  请问这个逻辑要怎么设计?    关键是从线程里去 arraylist 里取值的问题! 有哪位高手能指点指点?  

解决方案 »

  1.   

    public class Test
    {
        private ArrayList al = new ArrayList();
        public Test()
        {
            //除始化al
            al.Add("aa");
        }
        private string GetALValue()
        {
            Monitor.Enter(this);
            if (al.Count > 0)
            {
                string alv = al[0].ToString();
                al.RemoveAt(0);
            }
            Monitor.Exit(this);
        }
        //.....
    }
      

  2.   

    private object objectA = null;
    private object objectB = null;
    private object objectC = null;线程A里面的方法
    lock(arraylist)
    {
        objectA = //从list得到值
        arraylist.Remove//删除值
    }
    Process(objectA);线程B里面的方法
    lock(arraylist)
    {
        objectB = //从list得到值
        arraylist.Remove//删除值
    }
    Process(objectB);
      

  3.   

    datareader先取出来,再给常量,循环并行
      

  4.   

    你这是一个典型的任务(消息)队列问题。你把ArrayList里面的值放到Queue里面(Enqueue),然后启动10个线程来操作这个Queue,每次Dequeue一个出来。示例代码如下:arrayList to Queue;
    Thread[] threads = new Thread[10];
    foreach(thread
    ...
    start Thread(Method());
    ...void Method(queue){
    q = null;
    lock(typeof(Queue)){
      q = queue.Dequeue();
    }
    do q...
    }
    这些代码描述了大概的思路,具体内容自己添加吧。
      

  5.   

    看下这段代码,   我开一个线程  处理完 10000条 要 13 秒  开 10 个线程 处理完 10000条要 21 秒 ,怎么回事?
     private void button1_Click(object sender, EventArgs e)
            {
                #region  读取
                using (System.IO.StreamReader sr = new System.IO.StreamReader(this.txtRecePer.Text.Trim()))
                {
                    while (!sr.EndOfStream)
                    {                
                        al.Add(sr.ReadLine());                   
                    }
                }
                #endregion
                this.lblShow.Text = "总数:" + al.Count.ToString();
                int threadnum = Int32.Parse(txtThreads.Text.Trim());
                #region 线程分配
                 th = new System.Threading.Thread[threadnum];
               
                    //线程分配
                    for (int j = 0; j < threadnum; j++)
                    {
                        th[j] = new System.Threading.Thread(new System.Threading.ThreadStart(SetValues));
                        th[j].Name = "线程" + j.ToString();
                        th[j].IsBackground = true;
                        th[j].Start();
                    } 
                #endregion
            }
            private void SetValues()
            {
                
                while(al.Count>0)
                {
                    System.Threading.Monitor.Enter(al);
                    if (al.Count > 0)
                    {
                        string a = al[0].ToString();
                        if (this.rtbIng.InvokeRequired)
                        {
                            setControlValue scv = new setControlValue(InValues);
                            this.Invoke(scv, new object[] { System.Threading.Thread.CurrentThread.Name, a });
                        }
                        else
                        {
                            this.rtbIng.AppendText("[" + System.DateTime.Now + "]" + System.Threading.Thread.CurrentThread.Name + "--" + a + "\r\n");
                        }
                        al.RemoveAt(0);
                    }
                    else
                    {
                        break;
                    }
                    System.Threading.Monitor.Exit(al);
                } 
            }
            public  void InValues(string name, string info)
            {
                this.rtbIng.AppendText("["+System.DateTime.Now+"]"+ name + "--" + info + "\r\n");
            }
            //停止
            private void btnStop_Click(object sender, EventArgs e)
            {
                for (int i=0; i < th.Length; i++)
                {
                    th[i].Abort();
                }
            }
     
      

  6.   

    为什么要用多线程做这类操作?
    能讲一下你的需求吗?
    如果只是为了处理arraylist中的数据,用一个线程处理既快又省事,何必非要搞个多线程。
    如果是怕freezing UI ,用一个后台线程就行了。如果一定要这么处理,建议用下标来获取arraylist 中的内容,这样你只要在取下标的时加锁。
    object mylock=new object();
    int currentIndex;
    int GetCurrentIndex()
    {
       lock(mylock)
       {
          int i=currentIndex;
          currentIndex++;
          return i;
       }
    }void ProcessItem(object state)
    {
       int i=GetCurrentIndex();
       while(i<arraylist.Length)
       {
          object obj=arraylist[i];
          // process the item here
       }
    }void main()
    {
      for(int i=0;i<10;i++)
      {
          System.Threading.ThreadPool.QueueUserWorkItem(ProcessItem);
      }
    }
      

  7.   

    修改一下
    void ProcessItem(object state)
    {
       int i=GetCurrentIndex();
       while(i<arraylist.Length)
       {
          object obj=arraylist[i];
          // process the item here
          i=GetCurrentIndex();
       }
    }
      

  8.   

    修改一下
    void ProcessItem(object state)
    {
       int i=GetCurrentIndex();
       while(i<arraylist.Length)
       {
          object obj=arraylist[i];
          // process the item here
          i=GetCurrentIndex();
       }
    }
      

  9.   

    我弄个多线程来处理  一是怕 freezing UI   二是,对每个数据处理得慢,处理一个数据约2 秒,而等待处理数据量又庞大, 我想把速加起来,所以开多个线程同时去处理
      

  10.   

    在单核机器上跑多线程肯定要比单线程慢。
    (即使在多核机器上,还有一个线程亲和性的问题)
    线程和进程一样是要context switching 的。
    这就是为什么你用一个线程处理要比用多线程处理快的原因。
      

  11.   

    ArrayList如果仅仅是访问,线程是安全的
    如果要修改或者其他更改操作,
    //ArrayList iList = new ArrayList();
    lock(iList.SyncRoot)
    {
       //操作       
    }
      

  12.   


    ArrayList arr = ArrayList.Synchronized(new ArrayList());