C# 多线程 ThreadStart和ParameterizedThreadStart

C# 多线程 ThreadStart和ParameterizedThreadStart线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了CPU周期的浪费,同时提高了应用程序的效率。每个线程都定义了一个独特的控制流。如果应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。线程生命周期线程生命周期开始于System.Threading.Thread类的对象被创建时,结束于线程被终止或完成执行时。线程生命周期中的各种状态:未启动状态:当线程实例被创建但Start方法未被调用时的状况。就绪状态:

大家好,又见面了,我是你们的朋友全栈君。

线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了 CPU 周期的浪费,同时提高了应用程序的效率。每个线程都定义了一个独特的控制流。如果应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。

线程生命周期

线程生命周期开始于 System.Threading.Thread 类的对象被创建时,结束于线程被终止或完成执行时。

线程生命周期中的各种状态:

  • 未启动状态:当线程实例被创建但 Start 方法未被调用时的状况。
  • 就绪状态:当线程准备好运行并等待 CPU 周期时的状况。
  • 不可运行状态:下面的几种情况下线程是不可运行的:
    已经调用 Sleep 方法
    已经调用 Wait 方法
    通过 I/O 操作阻塞
  • 死亡状态:当线程已完成执行或已中止时的状况。

Thread 类常用的属性和方法

1、属性

属性 描述
CurrentContext 获取线程正在其中执行的当前上下文。
CurrentThread 获取当前正在运行的线程。
ExecutionContext 获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。
IsAlive 获取一个值,该值指示当前线程的执行状态。
IsBackground 获取或设置一个值,该值指示某个线程是否为后台线程。
IsThreadPoolThread 获取一个值,该值指示线程是否属于托管线程池。
ManagedThreadId 获取当前托管线程的唯一标识符。
Name 获取或设置线程的名称。
Priority 获取或设置一个值,该值指示线程的调度优先级。
ThreadState 获取一个值,该值包含当前线程的状态。

2、方法

方法 描述
public void Abort() 在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。
public static void ResetAbort() 取消为当前线程请求的 Abort。
public void Interrupt() 中断处于 WaitSleepJoin 线程状态的线程。
public void Join() 在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止为止。
public static Object GetData( LocalDataStoreSlot slot ) 在当前线程的当前域中从当前线程上指定的槽中检索值。
public static void SetData( LocalDataStoreSlot slot, Object data ) 在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。
public void Start() 开始一个线程。
public static void Sleep( int millisecondsTimeout ) 让线程暂停一段时间。
public static void SpinWait( int iterations ) 使线程等待由 iterations 参数定义的时间量。
public static bool Yield() 调用线程执行准备好在当前处理器上运行的另一个线程。由操作系统选择要执行的线程。

实例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ThreadTestConsoleApp
{ 
   
    class Program
    { 
   
        static void Main(string[] args)
        { 
   
            Thread[] newThreads = new Thread[4];
            for (int i = 0; i < newThreads.Length; i++)
            { 
   
                newThreads[i] =
                    new Thread(Slot.SlotTest);
                newThreads[i].Start();
            }
            Console.ReadKey();
        }
    }
    class Slot
    { 
   
        static Random randomGenerator = new Random();

        public static void SlotTest()
        { 
   
            Thread.SetData(
                Thread.GetNamedDataSlot("Random"),
                randomGenerator.Next(1, 200));

            Thread.Sleep(1000);

            Other o = new Other();
            o.ShowSlotData();
        }
    }

    public class Other
    { 
   
        public void ShowSlotData()
        { 
   
            Console.WriteLine("Other code displays data in thread_{0}'s data slot: {1,3}",
                AppDomain.GetCurrentThreadId().ToString(),
                Thread.GetData(
                Thread.GetNamedDataSlot("Random")).ToString());
        }
    }
}

结果:

Other code displays data in thread_{ 
   0}'s data slot: 199 Other code displays data in thread_{0}'s data slot: 119
Other code displays data in thread_{ 
   0}'s data slot: 36 Other code displays data in thread_{0}'s data slot: 98

以上实例演示了 线程的创建,睡眠以及SetData()和GetData()方法的运用。

其中newThreads[i] = new Thread(Slot.SlotTest);也可以写作:

 newThreads[i] = new Thread( new ThreadStart(Slot.SlotTest));

这两种写法的效果是一样的。都是创建一个线程。前者只是 C# 的语法,编译时编译器会自动转换成第二种的形式。ThreadStart 是线程的入口,可以理解为一个函数指针,指向线程将要运行的函数。

线程委托

1、ThreadStart
ThreadStart 是多线程的委托,所委托的方法不能有输入参数,返回值为void。

static void Main(string[] args)
{ 
   
	ThreadStart threadStart=new ThreadStart(Calculate);
	Thread thread=new Thread(threadStart);
	thread.Start();
}
public void Calculate()
{ 
   
   double Diameter=0.5;
   Console.Write("The Area Of Circle with a Diameter of {0} is {1}"Diameter,Diameter*Math.PI);
}

2、ParameterizedThreadStart
ParameterizedThreadStart的定义为void ParameterizedThreadStart(object state),使用这个委托定义的线程的启动函数可以接受一个输入参数,参数类型为object。object可以为一个类,进而达到传递多个参数的目的。
实例:

class AddParams
{ 
   
    public int a, b;

    public AddParams(int numb1, int numb2)
    { 
   
      a = numb1;
      b = numb2;
    }
}

class Program
{ 
   
    static void Main(string[] args)
    { 
   
      Console.WriteLine("***** Adding with Thread objects *****");
      Console.WriteLine("ID of thread in Main(): {0}",
        Thread.CurrentThread.ManagedThreadId);

      AddParams ap = new AddParams(10, 10);
      Thread t = new Thread(new ParameterizedThreadStart(Add));
      t.Start(ap);
      Console.ReadLine();
    }

    #region Add method
    static void Add(object data)
    { 
   
      if (data is AddParams)
      { 
   
        Console.WriteLine("ID of thread in Main(): {0}",
          Thread.CurrentThread.ManagedThreadId);

        AddParams ap = (AddParams)data;
        Console.WriteLine("{0} + {1} is {2}",
          ap.a, ap.b, ap.a + ap.b);
      }
    }
    #endregion
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/159633.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 什么是拉链表_女表拉链的

    什么是拉链表_女表拉链的原文地址:https://blog.csdn.net/xiepeifeng/article/details/42431027在数据仓库的数据模型设计过程中,经常会遇到这样的需求:1.数据量比较大;2.表中的部分字段会被update,如用户的地址,产品的描述信息,订单的状态等等;3.需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态,  比如,查看某一…

    2022年10月16日
    5
  • 常用shell命令归纳总结

    常用shell命令归纳总结

    2022年2月19日
    45
  • asp.net UpdatePanel的简单用法「建议收藏」

    asp.net UpdatePanel的简单用法「建议收藏」局部更新是ajax技术的最基本,也是最重要的用法,今天大概把asp.netajax中的局部更新控件updatepanel的用法记录下,大家可以共同探讨UpdatePanel控制页面的局部更新,这个更新功能依赖于scriptManger控件的EnablePartialRendering属性,如果这个属性设置为false局部更新会失去作用(scriptManger控件的EnablePart

    2022年7月23日
    24
  • 超标量处理器设计 姚永斌 前言 摘录

    超标量处理器设计 姚永斌 前言 摘录目前的通用处理器从指令集方面可分为 RISC 和 CISC CISC 伴随着处理器的诞生 最开始的处理器都是使用这种指令集 力求在一条指令内完成很多事情 并且使用尽可能多的指令 覆盖到各种各样的操作 这就可以降低对存储器的需求 并且简化编译器的设计 当存储器和编译器不在是问题时 RISC 产生了 因为 80 的 CISC 指令只在 20 被使用 则可以将经常使用的 20 的 CISC 指令使用硬件来实现 剩余 80 的指令可以使用软件来模拟 于是简化硬件的设计 也便于使用流水线 不像可以变化长度的 CISC 指令 RISC 指令采

    2025年7月4日
    3
  • JVM自动内存管理机制–读这篇就GO了

    之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾。这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享。Java自动内存管理机制包

    2022年2月16日
    38
  • A股管家股票自动交易软件系统,功能完善强大[通俗易懂]

    A股管家股票自动交易软件系统,功能完善强大[通俗易懂]                                    2013年的时候,有个广东的朋友说再用这款A股管家股票自动系统,我当时比较惊讶,以前想过要是有一款股票自动交易软件能偶尔代替我一下就好了,虽然是职业股民,但也经常遇到太忙的时候,实在没时间。然后就在朋友的推荐下,弄了一套试试,印象非常深刻,当天设了600…

    2022年6月22日
    135

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号