C#多线程代码示例

using System;
using System.Threading;

namespace MultiThreadDemo
{
    class Program
    {
        public static void threadfunc()
        {
            try
            {
                Console.WriteLine("Child thread starts");
                Thread.Sleep(1000);
            }
            catch (ThreadAbortException / *ex* /)
            {
                Console.WriteLine("Thread abort!");
            }
        }

        static void Main(string[] args)
        {
            ThreadStart func = new ThreadStart(threadfunc);
            Thread th = new Thread(func);

            th.Start();
            Thread.Sleep(500);

            th.Abort();

            Console.ReadLine();
        }
    }
}
ThreadStart 无需传参给线程函数时
using System;
using System.Threading;

// The ThreadWithState class contains the information needed for
// a task, and the method that executes the task.
//
public class ThreadWithState
{
    // State information used in the task.
    private string boilerplate;
    private int numberValue;

    // The constructor obtains the state information.
    public ThreadWithState(string text, int number)
    {
        boilerplate = text;
        numberValue = number;
    }

    // The thread procedure performs the task, such as formatting
    // and printing a document.
    public void ThreadProc()
    {
        Console.WriteLine(boilerplate, numberValue);
    }
}

// Entry point for the example.
//
public class Example
{
    public static void Main()
    {
        // Supply the state information required by the task.
        ThreadWithState tws = new ThreadWithState(
            "This report displays the number {0}.", 42);

        // Create a thread to execute the task, and then
        // start the thread.
        Thread t = new Thread(new ThreadStart(tws.ThreadProc));
        t.Start();
        Console.WriteLine("Main thread does some work, then waits.");
        //t.Join();
        //Console.WriteLine(
        //    "Independent task has completed; main thread ends.");
    }
}
// The example displays the following output:
//       Main thread does some work, then waits.
//       This report displays the number 42.
//       Independent task has completed; main thread ends.
ThreadStart 需传参给线程函数时
using System;
using System.Threading;

// The ThreadWithState class contains the information needed for
// a task, the method that executes the task, and a delegate
// to call when the task is complete.
//
public class ThreadWithState
{
    // State information used in the task.
    private string boilerplate;
    private int numberValue;

    // Delegate used to execute the callback method when the
    // task is complete.
    private ExampleCallback callback;

    // The constructor obtains the state information and the
    // callback delegate.
    public ThreadWithState(string text, int number,
        ExampleCallback callbackDelegate)
    {
        boilerplate = text;
        numberValue = number;
        callback = callbackDelegate;
    }

    // The thread procedure performs the task, such as
    // formatting and printing a document, and then invokes
    // the callback delegate with the number of lines printed.
    public void ThreadProc()
    {
        Console.WriteLine(boilerplate, numberValue);
        Thread.Sleep(3000);
        if (callback != null)
            callback(1);
    }
}

// Delegate that defines the signature for the callback method.
//
public delegate void ExampleCallback(int lineCount);

// Entry point for the example.
//
public class Example
{
    public static void Main()
    {
        // Supply the state information required by the task.
        ThreadWithState tws = new ThreadWithState(
            "This report displays the number {0}.",
            42,
            new ExampleCallback(ResultCallback)
        );

        Thread t = new Thread(new ThreadStart(tws.ThreadProc));

        / *
            默认情况,在新开启一个子线程的时候,他是前台线程,只有,将线程的IsBackground属性设为true;他才是后台线程
            当子线程是前台线程,则主线程结束并不影响其他线程的执行,只有所有前台线程都结束,程序结束
            当子线程是后台线程,则主线程的结束,会导致子线程的强迫结束
         * /
        t.IsBackground = true;

        t.Start();
        Console.WriteLine("Main thread does some work, then waits.");
        t.Join();
        Console.WriteLine(
            "Independent task has completed; main thread ends.");
    }

    // The callback method must match the signature of the
    // callback delegate.
    //
    public static void ResultCallback(int lineCount)
    {
        Console.WriteLine(
            "Independent task printed {0} lines.", lineCount);
    }
}
// The example displays the following output:
//       Main thread does some work, then waits.
//       This report displays the number 42.
//       Independent task printed 1 lines.
//       Independent task has completed; main thread ends.
ThreadStart 需传参给线程函数 + 需要接收线程中返回值,此时要传入回调函数给线程函数
using System;
using System.Threading;

public class Work
{
    public static void Main()
    {
        // Start a thread that calls a parameterized static method.
        Thread newThread = new Thread(Work.DoWork);
        newThread.Start(42);

        // Start a thread that calls a parameterized instance method.
        Work w = new Work();
        newThread = new Thread(w.DoMoreWork);
        newThread.Start("The answer.");

        Console.ReadLine();
    }

    public static void DoWork(object data)
    {
        Console.WriteLine("Static thread procedure. Data='{0}'", data);
    }

    public void DoMoreWork(object data)
    {
        Console.WriteLine("Instance thread procedure. Data='{0}'", data);
    }
}
// This example displays output like the following:
//       Static thread procedure. Data='42'
//       Instance thread procedure. Data='The answer.'
ParameterizedThreadStart
using System;
using System.Threading;

public class Example
{
    static Thread thread1, thread2;

    public static void Main()
    {
        thread1 = new Thread(ThreadProc);
        thread1.Name = "Thread1";
        thread1.Start();

        thread2 = new Thread(ThreadProc);
        thread2.Name = "Thread2";
        thread2.Start();


        Console.ReadLine();
    }

    static TimeSpan waitTime = new TimeSpan(0, 0, 2);
    private static void ThreadProc()
    {
        Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
        if (Thread.CurrentThread.Name == "Thread1" &&
            thread2.ThreadState != ThreadState.Unstarted)
            //thread2.Join();
            //if (thread2.Join(2000))
            //if (thread2.Join(waitTime))
            if (thread2.Join(TimeSpan.FromSeconds(2)))
                Console.WriteLine("Thread2 has termminated.");
            else
                Console.WriteLine("The timeout has elapsed and Thread1 will resume.");

        Thread.Sleep(4000);
        Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
        Console.WriteLine("Thread1: {0}", thread1.ThreadState);
        Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
    }
}
// The example displays output like the following:
//       Current thread: Thread1
//       
//       Current thread: Thread2
//       
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//       
//       
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped
Join 等待其它线程执行完,在此之前一直处于阻塞状态
using System;
using System.Security.Permissions;
using System.Threading;

class ThreadInterrupt
{
    static void Main()
    {
        StayAwake stayAwake = new StayAwake();
        Thread newThread =
            new Thread(new ThreadStart(stayAwake.ThreadMethod));
        newThread.Start();

        Thread.Sleep(500);
        // The following line causes an exception to be thrown 
        // in ThreadMethod if newThread is currently blocked
        // or becomes blocked in the future.
        newThread.Interrupt();
        Console.WriteLine("Main thread calls Interrupt on newThread.");

        // Tell newThread to go to sleep.
        stayAwake.SleepSwitch = true;

        // Wait for newThread to end.
        newThread.Join();


        Console.WriteLine("Main thread .");
    }
}

class StayAwake
{
    bool sleepSwitch = false;

    public bool SleepSwitch
    {
        set { sleepSwitch = value; }
    }

    public StayAwake() { }

    public void ThreadMethod()
    {
        Console.WriteLine("newThread is executing ThreadMethod.");
        while (!sleepSwitch)
        {
            // Use SpinWait instead of Sleep to demonstrate the 
            // effect of calling Interrupt on a running thread.
            Thread.SpinWait(60000000);  // 只是让CPU去执行一段没有用的代码。当时间结束之后继续执行其它代码,而不是重新参与CPU的竞争。
        }
        try
        {
            Console.WriteLine("newThread going to sleep.");

            // When newThread goes to sleep, it is immediately 
            // woken up by a ThreadInterruptedException.
            Thread.Sleep(Timeout.Infinite); // 是强制放弃CPU的时间片,然后重新和其他线程一起参与CPU的竞争。
        }
        catch (ThreadInterruptedException e)
        {
            Console.WriteLine("newThread cannot go to sleep - " +
                "interrupted by main thread.");
        }
    }
}
Interrupt 中断Sleep操作
using System;
using System.Threading;

class Test
{
    public static void Main()
    {
        Thread newThread = new Thread(new ThreadStart(TestMethod));
        newThread.Start();
        Thread.Sleep(1000);

        // Abort newThread.
        Console.WriteLine("Main aborting new thread.");
        newThread.Abort("Information from Main.");  //可为异常类提供异常信息

        // Wait for the thread to terminate.
        newThread.Join();
        Console.WriteLine("New thread terminated - Main exiting.");
    }

    static void TestMethod()
    {
        try
        {
            while (true)
            {
                Console.WriteLine("New thread running.");
                Thread.Sleep(1000);
            }
        }
        catch (ThreadAbortException abortException)
        {
            Console.WriteLine((string)abortException.ExceptionState);
        }
    }
}
Abort 中断线程
using System;
using System.Threading;

namespace InterlockedExchange_Example
{
    class MyInterlockedExchangeExampleClass
    {
        //0 for false, 1 for true.
        private static int usingResource = 0;

        private const int numThreadIterations = 5;
        private const int numThreads = 3;

        static void Main()
        {
            Thread myThread;
            Random rnd = new Random();

            for (int i = 0; i < numThreads; i++)
            {
                myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Thread{0}", i + 1);

                //Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000));
                myThread.Start();
            }

            Console.ReadLine();
        }

        private static void MyThreadProc()
        {
            for (int i = 0; i < numThreadIterations; i++)
            {
                UseResource();

                //Wait 1 second before next attempt.
                Thread.Sleep(1000);
            }
        }

        //A simple method that denies reentrancy.
        static bool UseResource()
        {
            //0 indicates that the method is not in use.
            if (0 == Interlocked.Exchange(ref usingResource, 1))
            {
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);

                //Code to access a resource that is not thread safe would go here.

                //Simulate some work
                Thread.Sleep(500);

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);

                //Release the lock
                Interlocked.Exchange(ref usingResource, 0);
                return true;
            }
            else
            {
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
                return false;
            }
        }
    }
}
Interlocked 为多线程共享的变量提供原子操作
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace WaitAndPulse
{
    public class LockMe
    {
    }

    class WaitPulse1
    {
        private int result = 0;
        private LockMe lM;

        public WaitPulse1()
        {
        }

        public WaitPulse1(LockMe l)
        {
            this.lM = l;
        }

        public void CriticalSection()
        {
            Monitor.Enter(this.lM);

            Console.WriteLine("WaitPulse1: Entered Thread "
                + Thread.CurrentThread.GetHashCode());

            //Thread.Sleep(1500);

            for (int i = 1; i <= 5; i++)
            {
                Monitor.Wait(this.lM);

                Console.WriteLine("WaitPulse1: WokeUp");
                Console.WriteLine("WaitPulse1: Result = "
                    + result++
                    + " ThreadID "
                    + Thread.CurrentThread.GetHashCode());

                Monitor.Pulse(this.lM);
            }
            Console.WriteLine("WaitPulse1: Exiting Thread "
                + Thread.CurrentThread.GetHashCode());

            Monitor.Exit(this.lM);
        }
    }

    class WaitPulse2
    {
        private int result = 0;
        private LockMe lM;

        public WaitPulse2()
        {
        }

        public WaitPulse2(LockMe l)
        {
            this.lM = l;
        }

        public void CriticalSection()
        {
            // 在指定对象上获取排他锁
            Monitor.Enter(this.lM);
          
            Console.WriteLine("WaitPulse2: Entered Thread "
                + Thread.CurrentThread.GetHashCode());

            for (int i = 1; i <= 5; i++)
            {
                // 通知等待队列中的线程锁定对象状态的更改
                // 目的是为了让另外一个线程中的Wait不阻塞
                Monitor.Pulse(this.lM);

                Console.WriteLine("WaitPulse2: Result = "
                    + result++
                    + " ThreadID "
                    + Thread.CurrentThread.GetHashCode());
               
                // 释放对象上的锁并阻止当前的线程,直到它重新获取该锁
                Monitor.Wait(this.lM);

                Console.WriteLine("WaitPulse2: WokeUp");
            }
            Console.WriteLine("WaitPulse2: Exiting Thread "
                + Thread.CurrentThread.GetHashCode());

            // 释放指定对象上的排他锁
            Monitor.Exit(this.lM);
        }
    }

    public class ClassForMain
    {
        public static void Main(string[] args)
        {
            LockMe l = new LockMe();

            WaitPulse1 e1 = new WaitPulse1(l);
            WaitPulse2 e2 = new WaitPulse2(l);

            Thread t1 = new Thread(new ThreadStart(e1.CriticalSection));
            t1.Start();

            Thread.Sleep(200);

            Thread t2 = new Thread(new ThreadStart(e2.CriticalSection));
            t2.Start();

            //Wait till the user enters something
            Console.ReadLine();
        }
    }
}
Monitor
//-------------------------------------------------------------------------------------
//  Monitor
//  线程优先顺序: 【拥有锁线程】> 【就绪队列】> 【等待队列】
//-------------------------------------------------------------------------------------

using System;
using System.Threading;
using System.Diagnostics;
using System.Collections;

public class ProgramMain
{
    const int MAX_LOOP_TIME = 10;
    private static Queue m_smpQueue = new Queue();
    private static object obj = new object();

    public class ThreadFunc
    {
        /// <summary>
        /// 将要处理的数据放入队列
        /// </summary>
        public void ThreadAFunc()
        {
            int count = 0;
            lock(obj)
            {
                Monitor.Pulse(obj);
                while (count < MAX_LOOP_TIME)
                {
                    Trace.WriteLine("ThreadA WriteLine");
                    m_smpQueue.Enqueue(count);

                    // 等待ThreadB处理数据!
                    // (当前线程释放同步锁;当前线程转入【等待队列】,直到当前线程再次转到【就绪队列】并再次获取锁才继续 否则一直阻塞)
                    Monitor.Wait(obj);
                    
                    // 让【等待队列】中的线程转入【就绪队列】(一旦当前线程不再拥有锁,就绪队列中的线程可以拥有锁)
                    Monitor.Pulse(obj);

                    count++;
                }
            }
        }

        /// <summary>
        /// 处理队列中数据
        /// </summary>
        public void ThreadBFunc()
        {
            lock (obj)
            {
                do
                {
                    if(m_smpQueue.Count > 0)
                    {
                        // 数据处理
                        int count = (int)m_smpQueue.Dequeue();
                        Console.WriteLine(count.ToString());
                        Trace.WriteLine("ThreadB WriteLine");
                        //Thread.Sleep(3000);
                    }
                    // 让【等待队列】中的线程转入【就绪队列】
                    Monitor.Pulse(obj);
                } while (Monitor.Wait(obj, 10000));   // 等待数据入队列(当前线程释放锁)
            }
        }
    }

    public static void Main(string[] args)
    {
        ThreadFunc a = new ThreadFunc();

        Thread ta = new Thread(new ThreadStart(a.ThreadAFunc));
        Thread tb = new Thread(new ThreadStart(a.ThreadBFunc));

        ta.Start();
        tb.Start();

        //Console.ReadLine();
    }
}
Monitor (Wait、Pulse) 

 参考  C# Monitor的Wait和Pulse方法使用详解

posted on 2019-09-12 15:46  jshchg  阅读(831)  评论(0编辑  收藏  举报

导航