第一个问题:
Thread ths = new Thread(new ThreadStart(sp.spider_T));
ths.Start();
例如,,,线程ths,,启动执行sp.spider_T中的方法,但是这个方法中又需要再产生几个线程,我是这样弄的
public void spider_s()
{
int n = Thread_s;
for (int i = 0; i < n; i++)
{
th[i] = new Thread(new ThreadStart(spider_l));
th[i].Name = "第" + i.ToString() + "个线程";
th[i].Start();
}
}
如果是这样的话工作一切都按照我的意思在处理,可是有一点。这个用for产生的线程,我在外部无法直接操作它,比如,挂起停止一类的。除非把th设成全局静态才能操作,但是同时有很多这样的任务执行的话根本不行,而且对ths这个主线程停止与挂起对里面的th是没有效果的。所以这里我不知道怎么在外部控制th这个线程。
---------------------------------------------------------------------------------
第二个问题
依旧是用for循环生成几个线程
for (int i = 0; i < n; i++)
{
th[i] = new Thread(new ThreadStart(spider_l));
th[i].Name = "第" + i.ToString() + "个线程";
th[i].Start();
}
比如spider_l方法中会实例化另一个类进行工作,问题就在这里。一个动态类实例化后里面的数据都是初始值,可是我需要这i个线程中其中几个线程需要调用这个类去处理一个任务,,其他几个处理另一个任务都要用到这个类。这样我怎么去处理这个类中的对某几个处理同一个任务的线程达到数据同步?
----------------------------------------------------------------------
可能我的表述有些混乱,这个还真是不好解释清楚。我不必需要高手同时解答这两个问题,只要能解答我其中一个问题我就给分。因为这两个问题随便一个都可以帮我解决眼前的问题。
第一个问题,用全局变量似乎也没问题,一般线程也不能无限制的去创建
第二个问题,在线程内实例对象,对象间的引用不一样,怎么会相互影响?
第一个问题,可以用全局变量,并且你要控制线程的个数的,不是线程越多就执行得越快。
第二个问题,要同步的话,那个类你不应该在spider_l方法中实例化,你应该在for的外面实例化,然后把实例化后的对象做为参数传给spider方法。对对象的数据进行操作的时候,你把它锁起来。可以这样锁
Monitor.Enter(this);//锁定,保持同步
然后在操作完以后解锁
Monitor.Exit(this);//取消锁定
这样多个线程就能同时操作同一个对象实现数据同步了。
第一个问题,你要操作线程必须得到线程的引用,定义一个全局变量没有什么不可,至于是静态变量还是实例化的变量要看你的需求了,如果你只要管理一份这样的线程数组那么静态的就满足了,如果要管理多份的建议你定义为实例变量,这样你只要得到这个对象的引用就可以操作这个对象拥有的线程数组。
这是我写的示意的一个类,如果看明白了,你的第一个问题就可以解决。
第二个问题,如果你多线程实例化的对象是被其他线程共享的话,那就要将资源锁住(lock),那么第一个进来的线程就可以初始化里面的数据了。
你第二个问题表达的很不清楚我不知道你在说什么,第一个问题我大概明白了,因此这里只回答第一个问题。
对ths这个主线程停止与挂起对里面的th是没有效果的
是的,所以你需要暴露出一些接口来控制它。废话不多说,看例子,这段代码会类似你的代码一样,先发起1个线程,然后在这个线程里再发起3个线程。几秒种后,3个线程中间的一个会被终止掉。
class ThreadRunner
{
private Thread[] threads = new Thread[3];
private bool[] stop = new bool[3];
public void Run()
{
for (int i = 0; i < threads.Length; i++)
{
var j = i;
threads[j] = new Thread(() =>
{
while (!stop[j])
{
Console.WriteLine("thread {0} is running...", j);
Thread.Sleep(2000);
}
Console.WriteLine("thread {0} finished", j);
});
threads[j].Start();
}
}
public void Stop(int num)
{
stop[num] = true;
}
}
static void Main(string[] args)
{
var runner = new ThreadRunner();
var t = new Thread(runner.Run);
t.Start();
Console.WriteLine("main thread finished");
Thread.Sleep(5000);
runner.Stop(2);
Console.Read();
}
以上只是示例,你需要根据你项目的实际情况做出修改,暴露出不同的接口。