zoukankan      html  css  js  c++  java
  • c#线程2

    多线程中很有可能存在争夺一个变量资源而产生死锁或者不被期望的结果。

    测试类;

        class TestClass
        {
            private int num = 100;
            private object objLock = new object();
    
            public void MissYou()
            {
                while (true)
                {
                    lock (objLock)
                    {
                        SomeTest();
                    }
                }
            }
    
            public void SomeTest()
            {
                ++num;
                if (num == 100)
                {
                    Console.WriteLine("我不是针对谁,在座的各位");
                }
                num = 100;
            }
        }

    多线程类:

        class Demo1
        {
            public void Test()
            {
                TestClass obj = new TestClass();
                Thread t1 = new Thread(obj.MissYou);
                t1.Start();
                Thread t2 = new Thread(obj.MissYou);
                t2.Start();
            }
    
            static void Main(string[] args)
            {
                Demo1 obj=new Demo1();
                obj.Test();
            }
        }

    如果没有lock锁,线程t1和t2会产生死锁,主要是对于公共资源num的占用不当;

    解决方式是lock(objLock)使得线程顺序执行,就不存争夺资源的情况,值得注意的是objLock是引用类型object。

    在很多时候需要同一时间执行多个线程,需要用到一点线程池的知识。

            public void ThreadMerthod(object para)
            {
                Console.WriteLine("开始下载...");
                Thread.Sleep(3000);
                Console.WriteLine("下载完毕...");
            }
    
            public void Test()
            {
                ThreadPool.QueueUserWorkItem(ThreadMerthod,123);
                ThreadPool.QueueUserWorkItem(ThreadMerthod, 123);
                ThreadPool.QueueUserWorkItem(ThreadMerthod, 123);
                ThreadPool.QueueUserWorkItem(ThreadMerthod, 123);
                ThreadPool.QueueUserWorkItem(ThreadMerthod, 123);
                ThreadPool.QueueUserWorkItem(ThreadMerthod, 123);
                ThreadPool.QueueUserWorkItem(ThreadMerthod, 123);
    
                Console.ReadLine();
            }

    需要注意的是线程池属于后台线程,多用于后台任务,需要加上Console.ReadLine()。

    任务和任务工厂的例子:

            public void Test2()
            {
                Task ta = new Task(Method2);
                ta.Start();
                Console.ReadLine();
            }
    
            public void Test3()
            {
                TaskFactory tf = new TaskFactory();
                Task t = tf.StartNew(Method2);
                Console.ReadLine();
            }

    任务和线程,任务其实是线程的一个特例,就像事件是委托的一种特殊实例类似,当然在这里的任务和任务工厂都属于后台线程,需要Console.ReadLine()。

  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/Optimism/p/10505397.html
Copyright © 2011-2022 走看看