[英]Multithreading not working - Create thread per loop index Java
我編寫了以下代碼,嘗試運行兩個線程以在for循環中調用函數,但是結果的時間相同,就好像我沒有多個線程地按順序運行它一樣。 有什么想法為什么這里的多線程不起作用? 有更好的方法嗎? 例如,如果我想有10個線程,使用我的代碼,這意味着我在創建線程時必須創建10個重復的run()函數,我想知道是否有更簡單的方法來設置線程數? 還有可能根據循環計數器創建多個線程,以便每個循環都創建一個線程來完成它,因此,如果我有10個循環,那么10個線程將同時運行以非常快地完成處理?
private Thread t1 = new Thread(){
public void run(){
for (int i = 0; i < 2; i++)
{
try {
myfn(i);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
private Thread t2 = new Thread(){
public void run(){
for (int i = 2; i < 4; i++)
{
try {
myfn(i);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
public Results getResults() throws IOException, SocketTimeoutException {
t1.start();
t2.start();
try {
t1.join(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
t2.join(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
為了在多個線程中運行同一任務,您可能正在尋找一個線程池。 Java為此提供了一個ThreadPoolExecutor
。
這是帶有以下示例的Java並發性介紹:
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(2);
return 123;
}
catch (InterruptedException e) {
throw new IllegalStateException("task interrupted", e);
}
});
future.get(1, TimeUnit.SECONDS);
該示例專門創建了一個僅具有單個線程的池,但是Executors.newFixedThreadPool
的參數控制將使用多少個線程。
從您最初的問題中我不能確定為什么您認為沒有利用兩個線程。
public class MyThead extend Thread{
private int initValue = 0;
private int upperBound = 0;
public MyThread(int init, int ub){
this.initValue = init;
this.upperBound = ub;
}
public void run(){
for(int i = init; i < upperBound; i++){
myfn(i);
}
}
}
創建線程並啟動它們:
List<Thread> threads = new ArrayList<>();
threads.add(new MyThread(0,2));
threads.add(new MyThread(2,4));
for(Thread t: threads){
t.start()
}
for(Thread t: threads){
t.join();
}
您不需要復制線程/循環10次,只需采用邏輯並適當地使用它即可。
public class ExampleThread extends Thread {
private final int start, iterations;
public ExampleThread(int start, int iterations) {
this.start = start;
this.iterations = iterations;
}
@Override public void run() {
for (int i = 0; i < iterations; i++) {
myfn(start + i);
}
}
}
int iterations = 2;
List<Thread> threads = new ArrayList<>();
for (int threadId = 0; threadId < 10; threadId++) {
threads.add(new ExampleThread(threadId * iterations, iterations));
}
threads.forEach(Thread::start);
threads.forEach(t -> {
try {
t.join(0);
} catch (Exception e) {
e.printStackTrace(System.err);
}
});
我編寫了以下代碼,嘗試運行兩個線程以在for循環中調用函數,但是結果的時間相同,就好像我沒有多個線程地按順序運行它一樣。
盡管沒有看到myfn(...)
代碼很難知道發生了什么,但是有很多原因可以導致這種情況發生。 以下是一些可能的原因:
myfn
運行得如此之快,以至於在不同線程中運行它的速度不會更快。 myfn
正在等待其他資源,在這種情況下,線程不能真正並發運行。 myfn
阻塞了IO(網絡或磁盤),即使您一次執行兩個(或多個),磁盤或遠程服務器也無法更快地處理增加的請求。 有更好的方法嗎? 例如,如果我想擁有10個線程,使用我的代碼,這意味着我必須創建10個重復的run()函數...
在這里要做的正確的事情是創建自己的類,該類接受上下限。 正確的方法是實現Runnable
,而不是擴展Thread
。 就像是:
public class MyRunnable implements Runnable {
private final int start;
private final int end;
public MyRunnable(int start, int end) {
this.start = start;
this.end = end;
}
public void run() {
for (int i = start; i < end; i++) {
myfn(i);
}
}
}
然后,您可以手動啟動線程,也可以使用ExecutorService
線程維護:
// this will start a new thread for every job
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.submit(new MyRunnable(0, 2));
threadPool.submit(new MyRunnable(2, 4));
// once you've submitted your last task, you shutdown the pool
threadPool.shutdown();
// then we wait until all of the tasks have run
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.