我想使用CPU的两个内核对矢量(数组)进行简单的数学运算。该程序无法正常工作。请解释我如何解决我的问题。
public class MyRunnable implements Runnable {
private int startIndex;
private int endIndex;
private float[] tab;
public MyRunnable(int startIndex, int endIndex, float[] tab)
{
this.startIndex = startIndex;
this.endIndex = endIndex;
this.tab = tab;
}
@Override
public void run()
{
System.out.println(Thread.currentThread());
for(int i = startIndex; i < endIndex; i++)
{
tab[i] = i * 2;
}
System.out.println("Finished");
}
}
public class Test {
public static void main(String[] args) {
int size = 10;
int n_threads = 2;
float tab[] = new float[size];
for(int i = 0; i < size; i++)
{
tab[i] = i;
}
System.out.println(Thread.currentThread());
for(int i = 0; i < size; i++)
{
System.out.println(tab[i]);
}
Runnable r1 = new MyRunnable(0, size / n_threads, tab );
Runnable r2 = new MyRunnable(size / n_threads, size, tab );
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
for(int i = 0; i < size; i++)
{
System.out.println(tab[i]);
}
}
答案 0 :(得分:2)
答案 1 :(得分:2)
正如其他人所指出的,你不是在等待你的线程完成执行。您应该遵循@Howard和@JK的建议,这将解决您的基本问题。如果您决定使用线程和并行处理做更多事情,虽然我强烈建议查看java.util.concurrent包 - 它们有许多有用的类,可以让您的生活更轻松。
我冒昧地使用Callable和ExecutorService重新编码您的示例。请参阅下面的示例代码:
public static void main(String[] args) {
int size = 10;
int n_threads = 2;
float tab[] = new float[size];
for (int i = 0; i < size; i++) {
tab[i] = i;
}
System.out.println(Thread.currentThread());
for (int i = 0; i < size; i++) {
System.out.println(tab[i]);
}
// Determine batch size, based off of number of available
// threads.
int batchSize = (int) Math.ceil((double) size / n_threads);
System.out.println("Size: " + size + " Num threads: " + n_threads
+ " Batch Size: " + batchSize);
// Create list of tasks to run
List<Callable<Object>> tasks = new ArrayList<Callable<Object>>(
n_threads);
for (int i = 0; i < n_threads; i++) {
tasks.add(Executors.callable(new MyRunnable(i * batchSize,
((i + 1) * batchSize) - 1, tab)));
}
// Create an executor service to handle processing tasks
ExecutorService execService = Executors.newFixedThreadPool(n_threads);
try {
execService.invokeAll(tasks);
} catch (InterruptedException ie) {
ie.printStackTrace();
} finally {
execService.shutdown();
}
for (int i = 0; i < size; i++) {
System.out.println(tab[i]);
}
}
在你的MyRunnable类中做了一个小改动,它正在跳过最后一个索引的处理:
@Override
public void run() {
System.out.println(Thread.currentThread());
for (int i = startIndex; i <= endIndex; i++) {
tab[i] = i * 2;
}
System.out.println("Finished");
}
效果很好,你可以自己测试一下。 java.util.concurrent中还有更多可以执行类似功能的类,可以随意浏览。
祝你好运!答案 2 :(得分:1)
您可以通过插入Thread.join()的调用来等待线程完成执行:
t1.join();
t2.join();
在x.start()
函数调用后暂停,直到线程完成。否则你无法知道它们是否已经完成执行。
您还应该考虑将单独线程中的tab[]
访问与mutex/semaphore or similar mechanism同步,而不必直接对传入的数组引用执行计算,因为这会限制并发数量(如果本)。