myObject A1 = new myObject();
        myObject A2 = new myObject();
        int i = -1;
        myObject[] A = new myObject[2];
        private void button1_Click(object sender, EventArgs e)
        {
            A[0] = A1;
            A[1] = A2;            System.Threading.Thread t1 = new System.Threading.Thread(Thread1);
            System.Threading.Thread t2 = new System.Threading.Thread(Thread1);
            t1.Start();
            t2.Start();
        }        private void Thread1()
        {
            i++;
            Console.WriteLine("t" + (i+1) +"线程开始了"); //注意这句代码
            lock (A[i].obj)
            {
                foreach (myObject c in A)
                {
                    c.i++;                    
                }
                Console.WriteLine(A[i].i.ToString());
                System.Threading.Thread.Sleep(10000);
                Console.WriteLine(A[i].i.ToString());
            }            //Console.WriteLine("t" + (i + 1) + "线程结束了");                  }
    }    public class myObject
    {
        public int i = 0;
        public object obj = new object();
        
    }
请高手看看上面这段代码,为什么把下面这句注销掉和不注销掉,输出的结果不一样?
Console.WriteLine("t" + (i+1) +"线程开始了"); //注意这句代码

解决方案 »

  1.   

    我想起来了你问过那个socket通信问题,这个必然会有繁琐的线程问题。
    我正好做了一个socket通信类库,贴出来一起研究一下。
    服务器部分public class Server
        {
            public byte[] buffers;
            Socket[] sockets;
            SocketAsyncEventArgs[] sendargs;
            SocketAsyncEventArgs[] recvargs;
            Queue<int>[] queues;
            Object[] objs;
            int[] states; 
            int recvbufferlen;
            int sendbufferlen;
            int sockcount;
            int allevbufferlen;
            int sendindex;
            Stack<int> sockstack;
            Object stackobj = new Object();
            Socket acceptsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            SocketAsyncEventArgs acceptargs = new SocketAsyncEventArgs();
            public event Action<int, int> RecvComplete;
            public event Action<int> AcceptComplete;
            public event Action<int> SendComplete;
            public event Action<int> CloseComplete;
            byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0x88, 0x13, 0, 0 }; 
            public Server(int skcount, int rvbufferlen, int sdbufferlen, int queuecount, string ipadr, int port)
            {
                buffers = new byte[skcount * rvbufferlen + sdbufferlen];
                sockets = new Socket[skcount];
                sendargs = new SocketAsyncEventArgs[skcount];
                recvargs = new SocketAsyncEventArgs[skcount];
                queues = new Queue<int>[skcount];
                objs = new Object[skcount];
                states = new int[skcount];
                recvbufferlen = rvbufferlen;
                sendbufferlen = sdbufferlen;
                sockcount = skcount;
                allevbufferlen = skcount * rvbufferlen;
                sendindex = 0;
                sockstack = new Stack<int>(skcount);
                for (int i = 0; i < skcount; i++)
                {
                    sockstack.Push(skcount - 1 - i);
                    sendargs[i] = new SocketAsyncEventArgs();
                    sendargs[i].UserToken = i;
                    recvargs[i] = new SocketAsyncEventArgs();
                    recvargs[i].UserToken = i;
                    queues[i] = new Queue<int>(queuecount);
                    objs[i] = new Object();
                    recvargs[i].SetBuffer(buffers, i * rvbufferlen, 2);
                    sendargs[i].SetBuffer(buffers, allevbufferlen + sendindex, rvbufferlen);
                    recvargs[i].Completed += new EventHandler<SocketAsyncEventArgs>(Receive_Completed);
                    sendargs[i].Completed +=new EventHandler<SocketAsyncEventArgs>(Send_Completed);
                }
                acceptargs.Completed +=new EventHandler<SocketAsyncEventArgs>(acceptargs_Completed);
                acceptsock.Bind(new IPEndPoint(IPAddress.Parse(ipadr), port));
                acceptsock.Listen(10);
                acceptsock.AcceptAsync(acceptargs);
            }
            void acceptargs_Completed(object sender, SocketAsyncEventArgs e)
            {
                int m = -1;
                if (e.SocketError == SocketError.Success && e.LastOperation == SocketAsyncOperation.Accept
                    && e.AcceptSocket != null)
                {
                    lock (stackobj)
                        m = sockstack.Pop();
                    sockets[m] = e.AcceptSocket;
                }
                e.AcceptSocket = null;
                acceptsock.AcceptAsync(e);
                if (m != -1)
                {
                    Interlocked.CompareExchange(ref states[m], 1, 0);
                    AcceptComplete.Invoke(m);
                    sockets[m].IOControl(IOControlCode.KeepAliveValues, inValue, null);
                    sockets[m].ReceiveAsync(recvargs[m]);
                }
            }
            void Receive_Completed(object sender, SocketAsyncEventArgs e)
            {
                bool yichang = false;
                int sockindx = e.Offset / recvbufferlen;
                if (e.SocketError == SocketError.Success)
                {
                    if (e.LastOperation == SocketAsyncOperation.Receive)
                    {
                        if (e.BytesTransferred > 0)
                        {
                            if (e.BytesTransferred == e.Count)
                            {
                                int os = sockindx * recvbufferlen;
                                int len = BitConverter.ToInt16(buffers, os);
                                if (e.Offset % recvbufferlen < 2)
                                    e.SetBuffer(os + 2, len - 2);
                                else
                                {
                                    int indx = getsendindex(len);
                                    Buffer.BlockCopy(e.Buffer, os, e.Buffer, indx, len);
                                    e.SetBuffer(os, 2);
                                    if (RecvComplete != null)
                                        RecvComplete.BeginInvoke(sockindx, indx, null, null);
                                }
                            }
                            else
                                e.SetBuffer(e.Offset + e.BytesTransferred, e.Count - e.BytesTransferred);
                        }
                        else
                            yichang = true;
                    }
                }
                else
                    yichang = true;
                if (yichang)
                {
                    CloseSocket(sockindx);
                }
                else
                    sockets[sockindx].ReceiveAsync(e);
                    
            }
            void Send_Completed(object sender, SocketAsyncEventArgs e)
            {
                bool busy = false;
                int indx = (int)e.UserToken;
                if (e.SocketError == SocketError.Success)
                {
                    if (e.LastOperation == SocketAsyncOperation.Send)
                    {
                        lock (objs[indx])
                        {
                            queues[indx].Dequeue();
                            if (queues[indx].Count > 0)
                                busy = true;
                        }
                        if (busy)
                        {
                            int sdindx = queues[indx].Peek();
                            e.SetBuffer(sdindx, BitConverter.ToInt16(buffers, sdindx));
                            try { sockets[indx].SendAsync(e); }
                            catch { }
                        }
                        if (SendComplete != null)
                            SendComplete.Invoke(indx);
                    }
                }
                else
                    CloseSocket(indx);
            }
            public int getsendindex(int len)
            {
                int index = (int)(((uint)Interlocked.Add(ref sendindex, len)) % sendbufferlen);
                if(index - len < 0)
                    index = (int)(((uint)Interlocked.Add(ref sendindex, len)) % sendbufferlen);
                return index - len + allevbufferlen;
            }
            public void Send(int sockindx, int sendindx)
            {
                bool busy = false;
                lock (objs[sockindx])
                {
                    if (queues[sockindx].Count > 0)
                        busy = true;
                    queues[sockindx].Enqueue(sendindx);
                }
                if (!busy)
                {
                    sendargs[sockindx].SetBuffer(sendindx, BitConverter.ToInt16(buffers, sendindx));
                    try { sockets[sockindx].SendAsync(sendargs[sockindx]); }
                    catch { }
                }
            }
            public void CloseSocket(int sockindx)
            {
                if (Interlocked.CompareExchange(ref states[sockindx],0,1) == 1)
                {
                    try
                    {
                        if (CloseComplete != null)
                            CloseComplete.Invoke(sockindx);
                        try { sockets[sockindx].Shutdown(SocketShutdown.Both); }
                        catch { }
                        finally { sockets[sockindx].Close(); }
                    }
                    catch { }
                    finally
                    {
                        lock (objs[sockindx])
                        {
                            sockets[sockindx] = null;
                            queues[sockindx].Clear();
                        }
                        lock (stackobj)
                            sockstack.Push(sockindx);
                    }
                }
            }
        }
      

  2.   

    客户端部分public class Client
        {
            public byte[] buffers;
            SocketAsyncEventArgs sendargs;
            SocketAsyncEventArgs recvargs;
            SocketAsyncEventArgs connargs;
            Queue<int> queues;
            Object objs;
            int state;
            int recvbufferlen;
            int sendbufferlen;
            int sendindex;
            Socket acceptsock;
            public event Action<int> RecvComplete;
            public event Action ConnComplete;
            public event Action SendComplete;
            public event Action CloseComplete;
            byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0x88, 0x13, 0, 0 }; 
            public Client(int rvbufferlen, int sdbufferlen, int queuecount, string ipadr, int port)
            {
                acceptsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                buffers = new byte[rvbufferlen + sdbufferlen];
                sendargs = new SocketAsyncEventArgs();
                recvargs = new SocketAsyncEventArgs();
                connargs = new SocketAsyncEventArgs();
                queues = new Queue<int>(queuecount);
                objs = new Object();
                recvbufferlen = rvbufferlen;
                sendbufferlen = sdbufferlen;
                sendindex = 0;
                connargs.Completed += new EventHandler<SocketAsyncEventArgs>(acceptargs_Completed);
                recvargs.Completed += new EventHandler<SocketAsyncEventArgs>(Receive_Completed);
                recvargs.SetBuffer(buffers, 0, 2);
                sendargs.Completed += new EventHandler<SocketAsyncEventArgs>(Send_Completed);
                sendargs.SetBuffer(buffers, recvbufferlen + sendindex, recvbufferlen);
                connargs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(ipadr), port);
                acceptsock.ConnectAsync(connargs);
            }
            public void Connect()
            {
                acceptsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                acceptsock.ConnectAsync(connargs);
            }
            void acceptargs_Completed(object sender, SocketAsyncEventArgs e)
            {
                if (e.SocketError == SocketError.Success && e.LastOperation == SocketAsyncOperation.Connect
                    && e.ConnectSocket != null)
                {
                    if (ConnComplete != null)
                        ConnComplete.Invoke();
                    Interlocked.CompareExchange(ref state, 1, 0);
                    acceptsock.IOControl(IOControlCode.KeepAliveValues, inValue, null);
                    acceptsock.ReceiveAsync(recvargs);
                }
                else
                    acceptsock.ConnectAsync(connargs);
            }
            void Receive_Completed(object sender, SocketAsyncEventArgs e)
            {
                bool yichang = false;
                if (e.SocketError == SocketError.Success)
                {
                    if (e.LastOperation == SocketAsyncOperation.Receive)
                    {
                        if (e.BytesTransferred > 0)
                        {
                            if (e.BytesTransferred == e.Count)
                            {
                                int len = BitConverter.ToInt16(buffers, 0);
                                if (e.Offset < 2)
                                    e.SetBuffer(2, len - 2);
                                else
                                {
                                    int indx = getsendindex(len);
                                    Buffer.BlockCopy(e.Buffer, 0, e.Buffer, indx, len);
                                    e.SetBuffer(0, 2);
                                    if (RecvComplete != null)
                                        RecvComplete.Invoke(indx);
                                }
                            }
                            else
                                e.SetBuffer(e.Offset + e.BytesTransferred, e.Count - e.BytesTransferred);
                        }
                        else
                            yichang = true;
                    }
                }
                else
                    yichang = true;
                if (yichang)
                {
                    CloseSocket();
                }
                else
                    acceptsock.ReceiveAsync(e);        }
            void Send_Completed(object sender, SocketAsyncEventArgs e)
            {
                bool busy = false;
                if (e.SocketError == SocketError.Success)
                {
                    if (e.LastOperation == SocketAsyncOperation.Send)
                    {
                        lock (objs)
                        {
                            queues.Dequeue();
                            if (queues.Count > 0)
                                busy = true;
                        }
                        if (busy)
                        {
                            int sdindx = queues.Peek();
                            e.SetBuffer(sdindx, BitConverter.ToInt16(buffers, sdindx));
                            try { acceptsock.SendAsync(e); }
                            catch { }
                        }
                        if (SendComplete != null)
                            SendComplete.BeginInvoke(null, null);
                    }
                }
                else
                    CloseSocket();
            }
            public int getsendindex(int len)
            {
                int index = (int)(((uint)Interlocked.Add(ref sendindex, len)) % sendbufferlen);
                if (index - len < 0)
                    index = (int)(((uint)Interlocked.Add(ref sendindex, len)) % sendbufferlen);
                return index - len + recvbufferlen;
            }
            public void Send(int sendindx)
            {
                bool busy = false;
                lock (objs)
                {
                    if (queues.Count > 0)
                        busy = true;
                    queues.Enqueue(sendindx);
                }
                if (!busy)
                {
                    sendargs.SetBuffer(sendindx, BitConverter.ToInt16(buffers, sendindx));
                    try { acceptsock.SendAsync(sendargs); }
                    catch { }
                }
            }
            public void CloseSocket()
            {
                if (Interlocked.CompareExchange(ref state, 0, 1) == 1)
                {
                    try
                    {
                        if (CloseComplete != null)
                            CloseComplete.Invoke();
                        try { acceptsock.Shutdown(SocketShutdown.Both); }
                        catch { }
                        finally { acceptsock.Close(); }
                    }
                    catch { }
                    finally
                    {
                        lock (objs)
                        {
                            acceptsock = null;
                            queues.Clear();
                        }
                    }
                }
            }
        }
      

  3.   

    无关系
    使用lock
    lock需要指定一个私有的变量,保证类的外部是无法访问的.
      

  4.   

    i++得上锁i++ 执行的操作是
    1.读取i的值
    2.i加1
    3.把上一步计算得的值存入i变量两个线程就可能出现
    线程一读I(假设为1)
    线程二读I(还为1)
    线程一把计算I+1(2)的值 并存入I
    线程一把计算I+1(2)的值 并存入I结果就出现了竞态
      

  5.   

    Console.WriteLine这个语句内部也有加锁的处理,所以结果会不同。
    干吗不lock(A)。