2012-07-09 21 views
0

我不确定这样的代码是否安全。我需要从DB中读取一个名称,并且我需要使用10个线程,每个名称都带一个名称,然后在run内部调用一个需要此名称作为参数的函数。在循环中创建线程的正确性

是10个线程适合运行英特尔酷睿i7 8GB内存的电脑?我如何知道我可以创建的可接受的线程数?这段代码是正确和安全的吗?

我在Dietel的书中发现,他们在Executor之前创建了新的线程。他们添加一行:PrintTask task1 = new PrintTask("thread1");

检查:http://www.deitel.com/articles/java_tutorials/20051126/JavaMultithreading_Tutorial_Part4.html),但发现在下面的方法(没有新的说法):http://www.vogella.com/articles/JavaConcurrency/article.html

换句话说,我应该在循环之前创建它们?两个引用使用不同的方法,我很困惑。其代码是正确的做法是:

 ExecutorService Executor = Executors.newFixedThreadPool(10); 

     while(resultSet.next()) 
      { 
       name=resultSet.getString("hname"); 
       MyRunnable worker = new MyRunnable(name); 

       Executor.execute(worker); 
       Counter++; 
     } 


    Executor.shutdown(); 
    System.out.println("thread shutdown"); 

// Wait until all threads are finish 
while (! Executor.isTerminated()) { 

} 
System.out.println("Finished all threads"); 

OR

MyRunnable task1 = new MyRunnable(name); 
MyRunnable task2 = new MyRunnable(name); 
MyRunnable task3 = new MyRunnable(name); 
MyRunnable task4 = new MyRunnable(name); 
MyRunnable task5 = new MyRunnable(name); 
MyRunnable task6 = new MyRunnable(name); 
MyRunnable task7 = new MyRunnable(name); 
MyRunnable task8 = new MyRunnable(name); 
MyRunnable task9 = new MyRunnable(name); 
MyRunnable task10 = new MyRunnable(name); 


     ExecutorService Executor = Executors.newFixedThreadPool(10); 

     while(resultSet.next()) 
      { 
       name=resultSet.getString("hname"); 
       MyRunnable worker = new MyRunnable(name); 

       Executor.execute(worker); 
       Counter++; 
     } 


    Executor.shutdown(); 
    System.out.println("thread shutdown"); 

// Wait until all threads are finish 
while (! Executor.isTerminated()) { 

} 
System.out.println("Finished all threads"); 

而且,在实现运行MyRunnable类的构造函数,我一定要明确地启动线程或是否Executor.execute(worker)足够在这种情况下, 。

+2

的可运行是*不*线程。他们只是有一个运行方法,告诉线程将最终执行它该做什么。是的,Executor负责启动和停止线程。 – Thilo 2012-07-09 04:42:17

+0

'MyRunnable.shutdown()'做了什么?你的意思是'Executor.shutdown()'? – Thilo 2012-07-09 04:43:10

+0

@Thilo:是的,它应该是'Executor.shutdown'。现在更正。 – 2012-07-09 04:52:01

回答

3

我会像改写它:

ExecutorService executor = Executors.newFixedThreadPool(10); 

while(resultSet.next()) 
{ 
    name=resultSet.getString("hname"); 
    MyRunnable worker = new MyRunnable(name); 
    executor.submit(worker); 
    counter++; 
} 


executor.shutdown(); 
System.out.println("thread shutdown"); 

executor.awaitTermination(60, TimeUnit.SECONDS); 
System.out.println("Finished all threads"); 

变量在较低的情况下,而不是awaitTermination的循环。

要使用的线程数量取决于几个因素:机器,任务的数量来执行的任务的“大小”等

+0

我怎样才能决定等待时间。 60秒可能足以确保所有子线程在我结束主线程之前完成?这就是为什么我使用空循环,我不能决定时间?我对吗 ? – 2012-07-09 05:08:27

+0

这是否意味着无需编写创建新的线程语句?也不需要在构造函数中明确地启动它? – 2012-07-09 05:09:45

+0

等待时间由您决定。时间应该代表你可以说“在这个时候,如果它没有完成,这意味着有什么问题......”的时间。它可以是100ms,也可以是1天......您不需要创建线程并启动线程,执行程序就是为了这样做而设计的,并且以高效的方式执行。 – tibo 2012-07-09 06:49:50

0

如果这是您的担心,那么您的第一个循环没有任何线程不安全。我唯一关心的是你用什么Counter变量:你知道你不能依赖它的价值在你的MyRunnable之内,对吧?

+0

我没有使用myrunnable里面的计数器。我发送它作为线程创建的计数器,但我发现这个计数器并不代表线程的数量,因为我有一个固定的池。我的构造函数是:'MyRunnable(String xname){this.name = xname;}'。没有任何东西可以告诉我的线程启动?不确定。 – 2012-07-09 07:25:27