+ -
当前位置:首页 → 问答吧 → 多线程的时候,为什么同时只有1-2个线程在running。。

多线程的时候,为什么同时只有1-2个线程在running。。

时间:2011-12-20

来源:互联网

多线程的时候,为什么同时只有1-2个线程在running。。

而其他线程却都在WaitSleepJoin

看了一下线程池。。没有啥问题。。

至于这种情况,该如何解决? 

望大虾们不吝赐教。。

不胜感激。。

作者: zhuoweizhao   发布时间: 2011-12-20

.Net会自动管理线程运行状态,多个线程切换的时候会影响效率,所以一般有多少个cpu就运行多少个线程,

作者: stonespace   发布时间: 2011-12-20

CPU多少个,最多就多少个线程同时运行,所谓的多线程,要在其它线程被阻塞的情况下才有机会运行到。
例如调用Sleep(1),再如Socekt.Receive。这些会等待的方法,停下来就会让其它线程运行。

作者: qldsrx   发布时间: 2011-12-20

引用 1 楼 stonespace 的回复:

.Net会自动管理线程运行状态,多个线程切换的时候会影响效率,所以一般有多少个cpu就运行多少个线程,


怎么会跟CPU扯上关系呢?印象中,好像跟这个没啥关系的吧

作者: zhuoweizhao   发布时间: 2011-12-20

另外,你的线程如果访问界面或者Dictionary之类的对象的时候,内部会自动锁住同步对象,而进入WaitSleepJoin状态,很正常,

作者: stonespace   发布时间: 2011-12-20

线程也是用cpu来执行的,一个cpu同一个时间只能执行一个线程,没有空闲的cpu,线程就无法执行,

线程数远远多于cpu数目的时候,.Net会划分时间片,一个cpu在这个时间片运行线程1,下一个时间片运行线程2,这样就出现线程切换,其实很耗资源,影响效率,

引用 3 楼 zhuoweizhao 的回复:
引用 1 楼 stonespace 的回复:

.Net会自动管理线程运行状态,多个线程切换的时候会影响效率,所以一般有多少个cpu就运行多少个线程,


怎么会跟CPU扯上关系呢?印象中,好像跟这个没啥关系的吧

作者: stonespace   发布时间: 2011-12-20

引用 5 楼 stonespace 的回复:

线程也是用cpu来执行的,一个cpu同一个时间只能执行一个线程,没有空闲的cpu,线程就无法执行,

线程数远远多于cpu数目的时候,.Net会划分时间片,一个cpu在这个时间片运行线程1,下一个时间片运行线程2,这样就出现线程切换,其实很耗资源,影响效率,

引用 3 楼 zhuoweizhao 的回复:
引用 1 楼 stonespace 的回复:

.Net会自动管理线程运行……


真的没有办法强制唤醒其他线程吗?

作者: zhuoweizhao   发布时间: 2011-12-20

不过你的线程处于WaitSleepJoin可能是因为锁定同步对象造成的,不同线程访问同一个界面元素的时候,会互斥,.Net会不让多个线程同时访问一个对象,这样只有一个线程能访问,其他线程进入WaitSleepJoin排队等候这个线程访问完之后再恢复执行状态,

.Net有很多“线程安全”的对象,这些对象内部都有互斥锁,只允许一个线程访问它,多个线程访问的时候就会进入WaitSleepJoin状态,

作者: stonespace   发布时间: 2011-12-20

一般不行,线程需要资源才能运行,包括cpu,包括申请的互斥锁,如果当时线程申请的资源缺乏,它就只能进入WaitSleepJoin等待,

引用 6 楼 zhuoweizhao 的回复:
引用 5 楼 stonespace 的回复:

线程也是用cpu来执行的,一个cpu同一个时间只能执行一个线程,没有空闲的cpu,线程就无法执行,

线程数远远多于cpu数目的时候,.Net会划分时间片,一个cpu在这个时间片运行线程1,下一个时间片运行线程2,这样就出现线程切换,其实很耗资源,影响效率,

引用 3 楼 zhuoweizhao 的回复:
引用 1 楼 stonesp……

作者: stonespace   发布时间: 2011-12-20

引用 7 楼 stonespace 的回复:

不过你的线程处于WaitSleepJoin可能是因为锁定同步对象造成的,不同线程访问同一个界面元素的时候,会互斥,.Net会不让多个线程同时访问一个对象,这样只有一个线程能访问,其他线程进入WaitSleepJoin排队等候这个线程访问完之后再恢复执行状态,

.Net有很多“线程安全”的对象,这些对象内部都有互斥锁,只允许一个线程访问它,多个线程访问的时候就会进入WaitSleepJoin……

C# code

DataTable dt = GetOrderData(iThreadCount);

            if (dt != null && dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    strSalesOrderName = dt.Rows[i]["name"].ToString();
                    Thread scoreThread = new Thread(new ThreadStart(Execute));
                    scoreThread.Start();
                    scoreThread.Name = "线程" + i.ToString();
                    aList.Add(scoreThread.ManagedThreadId);
                    theadList.Add(scoreThread);
                }
            }



这是我的一部分代码。。会不会是这段代码有什么问题?

作者: zhuoweizhao   发布时间: 2011-12-20

这段代码没什么问题,唯一问题是创建线程太多,

关键是你的Execute方法,内部不要访问太多“共享数据”,

作者: stonespace   发布时间: 2011-12-20

这是我的Execute方法。
C# code

 private void Execute()
        {
            ScoreService.Score _score = new ScoreService.Score();
            try
            {
                _score.QueryTest(strSalesOrderName);
                _score.Demo(strSalesOrderName);
            }
            catch (Exception)
            {
            }
        }



其中的strSalesOrderName变量是在下面的循环里赋的值
C# code

  if (dt != null && dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    strSalesOrderName = dt.Rows[i]["name"].ToString();
                    Thread scoreThread = new Thread(new ThreadStart(Execute));
                    scoreThread.Start();
                    scoreThread.Name = "线程" + i.ToString();
                    aList.Add(scoreThread.ManagedThreadId);
                    theadList.Add(scoreThread);
                }
            }

作者: zhuoweizhao   发布时间: 2011-12-20

你的_score.QueryTest和_score.Demo都要访问数据库吧?那么线程被阻塞进入WaitSleepJoin状态是很正常的,

线程进入WaitSleepJoin状态说明它们正在访问数据库,等待数据库返回数据,数据库没有返回数据之前,这些线程当然是不能运行,

作者: stonespace   发布时间: 2011-12-20

相关阅读 更多