zoukankan      html  css  js  c++  java
  • 多线程之向线程传递参数

    总体来说多线程中向线程传递参数有3种方式

    1. 创建对象,初始化对象中的一些值,然后在Start()方法中调用该对象方法
    2. 通过lambda表达式
    3. Thread.Start方法

    先看代码:

         static void Count(object iterations)
            {
                CountNumbers((int)iterations);
            }
    
            static void CountNumbers(int iterations)
            {
                for (int i = 1; i <= iterations; i++)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(0.5));
                    Console.WriteLine("{0} prints {1}", Thread.CurrentThread.Name, i);
                }
            }
    
            static void PrintNumber(int number)
            {
                Console.WriteLine(number);
            }
    
            class ThreadSample
            {
                private readonly int _iterations;
    
                public ThreadSample(int iterations)
                {
                    _iterations = iterations;
                }
                public void CountNumbers()
                {
                    for (int i = 1; i <= _iterations; i++)
                    {
                        Thread.Sleep(TimeSpan.FromSeconds(0.5));
                        Console.WriteLine("{0} prints {1}", Thread.CurrentThread.Name, i);
                    }
                }
            }
            static void Main(string[] args)
            {
           //首先创建了ThreadSample类的一个对象,并提供了一个迭代次数
    var sample = new ThreadSample(10);

           (1)第一种方式.自定义类的方式        //使用ThreadSample对象的CountNumbers方法启动线程
           //该方法运行在另一个线程中,但是使用数字10,该数字是通过ThreadSample对象的构造函数传入的
    var threadOne = new Thread(sample.CountNumbers);(我们只是使用相同的间接方式将该迭代次数传递给另一个线程) threadOne.Name = "ThreadOne"; threadOne.Start(); threadOne.Join(); Console.WriteLine("--------------------------");       
           (2)第二种方式:使用Thread.Start方法,这种方式object只能传单个参数
           //另一种传递数据的方式是使用Thread.Start方法(为了应用该方法,在线程中启动的方法必须接受object类型的单个参数)
    var threadTwo = new Thread(Count); threadTwo.Name = "ThreadTwo"; threadTwo.Start(8); threadTwo.Join(); Console.WriteLine("--------------------------");
           (3)第三种方式:使用lambda表达式。lambda表达式定义了一个不属于任何类的方法
           //我们创建了一个方法,该方法使用需要的参数调用了另一个方法,并在另一个线程中运行该方法
    var threadThree = new Thread(() => CountNumbers(12)); threadThree.Name = "ThreadThree"; threadThree.Start(); threadThree.Join(); Console.WriteLine("--------------------------");        
           //当在lambda表达式中使用任何局部变量时, C#会生成一个类,并将该变量作为该类的一个属性。所以实际上该方式与 threadOne线程中使用的一样,但是我们无须定义该类, C#编译器会自动帮我们实现
           
           //这也会导致一个问题,如果在多个lambda表达式中使用相同的变量,它们会共享该变量值
           //它们都会打印20,因为在这两个线程启动之前变量被修改为20。
    int i = 10; var threadFour = new Thread(() => PrintNumber(i)); i = 20; var threadFive = new Thread(() => PrintNumber(i)); threadFour.Start(); threadFive.Start(); Console.Read(); }

    运行结果:

    对代码的分析和总结:

      当主程序启动时,首先创建了ThreadSample类的一个对象,并提供了一个迭代次数。然后使用该对象的CountNumbers方法启动线程。该方法运行在另一个线程中,但是使用数字10,该数字是通过ThreadSample对象的构造函数传入的。因此,我们只是使用相同的间接方式将该迭代次数传递给另一个线程。

      另一种传递数据的方式是使用Thread.Start方法。该方法会接收一个对象,并将该对象,传递给线程。为了应用该方法,在线程中启动的方法必须接受object类型的单个参数。在创建threadTwo线程时演示了该方式。我们将8作为一个对象传递给了Count方法,然后 Count方法被转换为整型。

      接下来的方式是使用lambda表达式。lambda表达式定义了一个不属于任何类的方法。我们创建了一个方法,该方法使用需要的参数调用了另一个方法,并在另一个线程中运行该方法。当启动threadThree线程时,打印出了12个数字,这正是我们通过lambda表达式传递,的数字。

      使用lambda表达式引用另一个C#对象的方式被称为闭包。当在lambda表达式中使用任何局部变量时, C#会生成一个类,并将该变量作为该类的一个属性。所以实际上该方式与 threadOne线程中使用的一样,但是我们无须定义该类, C#编译器会自动帮我们实现。

      这可能会导致几个问题。例如,如果在多个lambda表达式中使用相同的变量,它们会共享该变量值。在前一个例子中演示了这种情况。当启动threadFour和threadFive线程时,.它们都会打印20,因为在这两个线程启动之前变量被修改为20。

  • 相关阅读:
    Spring整合hibernate4:事务管理
    eclipse添加约束文件
    转]@SuppressWarnings 详解
    spring + springMVC +hibernate 配置2
    spring +spring+ hibernate配置1
    eclipse下 hibernate逆向数据库操作示例!!
    Spring+hibernate 配置实例
    dubbo接口快速测试技巧
    Spring Boot Starter列表
    Spring Boot Starters是什么?
  • 原文地址:https://www.cnblogs.com/gougou1981/p/12322764.html
Copyright © 2011-2022 走看看