net 中多线程有几种实现方法

net 中多线程有几种实现方法,第1张

1:UI线程。这个线程是 *** 作系统自动创建的,你画了个winform,那么程序一启动,自然有了这么个线程。值得注意的是,你添加一个Timer控件,现实的多线程,实际上,依然在UI线程里。只是定时被Timer夺去控制权而已,本质上依然是单线程。另一个线索也可以论证:本来非UI线程想更新UI界面,是需要利用delegate,involk等来实现的,但是在timer控件的线程里,是不需要的。
2:Thread thread = new Thread(objfunctionName); threadstart();
这样自定义的线程是真正的多线程,它的使用也是最灵活的。不像Timer线程,精确度只有50ms。值得注意的是:如果需要启动的线程函数是带输入参数的,怎么办?
有两个办法:
A:你不是启动obj对象里的函数吗?在threadstart();之前,你先添加这句话 MyObject obj = new MyObject(int a ,int b); 这样,objfunctionName函数里可以直接使用a和b了。还有个方法,就是利用委托封装函数,然后threadstart(参数);具体代码如下:
[ComVisibleAttribute(false)]
public delegate void ParameterizedThreadStart(Object obj)
//这个Thread类的构造方法的定义如下:
public Thread(ParameterizedThreadStart start);
public static void myStaticParamThreadMethod(Object obj)
{
ConsoleWriteLine(obj);
}

static void Main(string[] args)
{
Thread thread = new Thread(myStaticParamThreadMethod);
threadStart("通过委托的参数传值");
}
3:利用threadpool线程池技术。threadpool的主要原理是池里面的线程不会完成一个任务就消亡,而是会继续执行其他的任务,这减少了线程的消亡和生成的代价。
主要是ThreadPoolQueueUserWorkItem()和ThreadPoolRegisterWaitForSingleObject(···)两个静态函数。具体如下:
QueueUserWorkItem的使用:
static void ThreadProc(Object stateInfo)
{
ConsoleWriteLine("Hello from the thread pool");
}
Main函数里ThreadPoolQueueUserWorkItem(new WaitCallback(ThreadProc)); 即可。(注意WaitCallback系统委托),它的功能就像第2种方法里提到的new thread。
那么RegisterWaitForSingleObject是干什么的呢?这个方法的做用是向线程池添加一个可以定时执行的方法。有点像第一种方法里提到的timer线程,却不属于UI线程。
具体的使用如下:
AutoResetEvent wait = new AutoResetEvent(false);
object state = new object();
ThreadPoolRegisterWaitForSingleObject(wait, new WaitOrTimerCallback(test), state, 5000, false);
//5000是间隔调用的时间,也就是wait变量卡住的timeout时间(我觉得内部是这样实现的)
waitSet(); //如果有set这句话,那么第一次执行不用等5秒,则直接执行目标函数,否则没这句话,第一次执行要等5秒的。
还有一个要注意:我平常使用的是ManualResetEvent,但在threadpool里,首先要选的是AutoResetEvent,因为AutoResetEvent能自动reset,所以下一次间隔来了,又要重新等待5秒钟,达到定时器的目的。如果是ManualResetEvent,要么一次执行不了(初始值为false),要么不间断的玩命执行。
ManualResetEvent和AutoResetEvent的另一个重要区别是前者能一次唤醒多个线程,而后者一次只能唤醒一个线程。
其实RegisterWaitForSingleObject函数的使用有点想我封装好的MyTimer类的实现了:我里面的while死循环里用了个waitwaitone(2000,false);即可。
对了,说到这里,RegisterWaitForSingleObject函数实现的定时器,如果手动停止呢?
这要用到Unregister函数:
RegisteredWaitHandle rw = ThreadPoolRegisterWaitForSingleObject(wait, new WaitOrTimerCallback(test), state, 3000, false);
rwUnregister(wait);
嗯讨论了这么多线程的东西,干脆再说一个小点:ThreadIsBackground=true的时候,指示该线程为后台线程。后台线程将会随着主线程的退出而退出

1、使用pthread库执行多线程,这个是Linux下的线程库 Windows下应该有自己的API,不过这种东西一般还是以Linux为标准。pthread_create()创建一个线程,传入fun()的函数指针就行了。
2、例程:
#include <pthreadh>
#include <stdioh>
#include <sys/timeh>
#include <stringh>
#define MAX 10
pthread_t thread[2];
pthread_mutex_t mut;
int number=0, i;
void thread1()
{
printf ("thread1 : I'm thread 1\n");
for (i = 0; i < MAX; i++)
{
printf("thread1 : number = %d\n",number);
pthread_mutex_lock(&mut);
number++;
pthread_mutex_unlock(&mut);
sleep(2);
}
printf("thread1 :主函数在等我完成任务吗?\n");
pthread_exit(NULL);
}
void thread2()
{
printf("thread2 : I'm thread 2\n");
for (i = 0; i < MAX; i++)
{
printf("thread2 : number = %d\n",number);
pthread_mutex_lock(&mut);
number++;
pthread_mutex_unlock(&mut);
sleep(3);
}
printf("thread2 :主函数在等我完成任务吗?\n");
pthread_exit(NULL);
}
void thread_create(void)
{
int temp;
memset(&thread, 0, sizeof(thread)); //comment1
/创建线程/
if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0) //comment2
printf("线程1创建失败!\n");
else
printf("线程1被创建\n");
if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0) //comment3
printf("线程2创建失败");
else
printf("线程2被创建\n");
}
void thread_wait(void)
{
/等待线程结束/
if(thread[0] !=0) { //comment4
pthread_join(thread[0],NULL);
printf("线程1已经结束\n");
}
if(thread[1] !=0) { //comment5
pthread_join(thread[1],NULL);
printf("线程2已经结束\n");
}
}
int main()
{
/用默认属性初始化互斥锁/
pthread_mutex_init(&mut,NULL);
printf("我是主函数哦,我正在创建线程,呵呵\n");
thread_create();
printf("我是主函数哦,我正在等待线程完成任务阿,呵呵\n");
thread_wait();
return 0;
}

1、 认识Thread和Runnable
Java中实现多线程有两种途径:继承Thread类或者实现Runnable接口。Runnable是接口,建议用接口的方式生成线程,因为接口可以实现多继承,况且Runnable只有一个run方法,很适合继承。在使用Thread的时候只需继承Thread,并且new一个实例出来,调用start()方法即可以启动一个线程。
Thread Test = new Thread();
Teststart();
在使用Runnable的时候需要先new一个实现Runnable的实例,之后启动Thread即可。
Test impelements Runnable;
Test t = new Test();
Thread test = new Thread(t);
teststart();
总结:Thread和Runnable是实现java多线程的2种方式,runable是接口,thread是类,建议使用runable实现java多线程,不管如何,最终都需要通过threadstart()来使线程处于可运行状态。
2、 认识Thread的start和run
1) start:
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
2) run:
run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
3、 线程状态说明
线程状态从大的方面来说,可归结为:初始状态、可运行状态、不可运行状态和消亡状态,具体可细分为上图所示7个状态,说明如下:
1) 线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了thread实例后,线程就进入了初始状态;
2) 当该对象调用了start()方法,就进入可运行状态;
3) 进入可运行状态后,当该对象被 *** 作系统选中,获得CPU时间片就会进入运行状态;
4) 进入运行状态后case就比较多,大致有如下情形:
·run()方法或main()方法结束后,线程就进入终止状态;
·当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片;
·当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被锁牢(synchroniza,lock),将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待OS分配CPU时间片;
·当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。
·当线程调用stop方法,即可使线程进入消亡状态,但是由于stop方法是不安全的,不鼓励使用,大家可以通过run方法里的条件变通实现线程的stop。

1、继承Thread类实现多线程:

代码如下图。在Demo类中继承Thread类并覆写了run方法,在主方法中调用Demo对象d1,d2实现了两个线程同时运行的目的

2、实现Runnable接口实现多线程:

代码如下图。同样是Demo类我们实现了Runnable接口,同样覆写了run方法,在主方法中利用Demo类的对象来新建Thread类的对象从而实现两个线程同时运行的目的。

有时候感觉自己是个效率很高的人,有时候又觉得其实什么都没有做,那些在做的事情似乎都可以放下不管,无所事事,等deadline来的时候,一下子就都慌乱起来,结果就会越来越陷入这个循环里。

线程1:

家庭系列类网课,

每周1-2次集中线上学习,1-2次线上练习,线下1-2次复习,看书5本以上。

线程2:

导师班学习,

隔周1次线下学习,看书,每周1-2次复盘学习

线程3:

每周2次三级修学学习,

每天2小时左右自学、每周1-2次准备分享内容

线程4:

每周一次婚姻家庭咨询师志愿者服务

隔月督导,隔月讲座

准备督导材料、讲座材料

线程5:

每月讲师志愿者活动,

准备讲稿内容、素材,组织讲座

线程6:

Daily:复习备考社工考试

线程7:

Daily:复习备考lies

线程8:

热线小组

drm组长工作、每周一次线上热线、线上/线下隔周朋辈督导

hd每周一次线下热线+现场督导

线程9:

自己带的团体——

读书会:每周一次线上分享、每周排班

助人小组:每周一次地面学习

oh卡:最近组织暑期系列地面活动

线程10:

每周3-4次,对外汉语教学

线程11:

哲学读书会

已经掉了无数的课…

线程12:

督导学习

hd每月两次线下团体督导

zxzj每天线上督导或公开学习观摩课

线程13:

xs:短视频拍摄

目前项目进度0

线程14/15/…

计划中的需要学习的系列课程——

9月开始一年的沙盘;

8月开始1年的叙事;

……

不要理我——已碎,低头捡ing。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12608853.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存