如何通过仅使用单个线程来检查多线程的性能?
How to check performace of Multi Threading over using only a single thread?
我正在研究 Java 多线程并尝试检查多个线程的性能 threads.I 我正在尝试检查多线程是否比单线程更好。
所以,我写了一个代码来限制总和。
当 limit 变大时,它按我预期的方式工作(多线程比单线程快),但当 limit 小到 100000L 时却没有。
这是由于上下文切换吗?下面的代码是否适合检查多线程的性能?
public class MultiThreadingSum {
long count = 0;
static long limit = 1000000000L;
static void compareMultipleThreadToSingleThread(int threadCnt) {
Runnable r = () -> {
MultiThreadingSum mts = new MultiThreadingSum();
long startTime = System.nanoTime();
while(++mts.count<=limit);
long endTime = System.nanoTime();
long estimatedTime = endTime - startTime;
double seconds = estimatedTime / 1000000000.0;
System.out.println(Thread.currentThread().getName()+", elapsed time : "+seconds);
};
for(int i=0; i<threadCnt; i++) {
new Thread(r, "multiThread"+i).start();
}
Runnable r2 = () -> {
MultiThreadingSum mts = new MultiThreadingSum();
long startTime = System.nanoTime();
while(++mts.count<=limit*threadCnt);
long endTime = System.nanoTime();
long estimatedTime = endTime - startTime;
double seconds = estimatedTime / 1000000000.0;
System.out.println(Thread.currentThread().getName()+", elapsed time : "+seconds);
};
new Thread(r2, "singleThread").start();
}
public static void main(String[] args) {
compareMultipleThreadToSingleThread(3);
}
}
这不是一个很好的例子。多线程和单线程解决方案 运行 同时在同一个柜台上。所以实际上你 运行 一个有四个线程的多线程进程。您需要 运行 一个解决方案,直到线程完成并关闭,然后是另一个。最简单的解决方案是 运行 单线程进程作为 main 方法中的简单循环,运行 循环完成后的多线程解决方案。另外,我会有两个单独的计数器,或者,您可以在单线程循环完成后将零分配给计数器
您的代码不会在 运行 单线程实验之前等待 3 线程实验完成。所以你可能会污染你的结果。
您的代码似乎不必要地复杂。我们不能 运行 两个单独的实验,一个有 3 个线程,一个有 1 个线程,分别重用代码吗?
在现代 Java 中,我们很少需要解决 Thread
class。相反,使用添加到 Java 5.
的执行程序服务框架
综上所述,也许您的实验应该更像下面这样。
警告:这只是一个非常粗略的剪辑,我没有考虑清楚,我的咖啡因已经耗尽。因此,请深思熟虑地修改此代码。也许我可以在一两天内修改这段代码。
package work.basil.threading;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Loopy
{
public static void main ( String[] args )
{
Loopy app = new Loopy();
List < Integer > inputThreadsLimit = List.of( 1 , 3 , ( Runtime.getRuntime().availableProcessors() - 1 ) );
for ( Integer numberOfThreads : inputThreadsLimit )
{
System.out.println("----------| Experiment for thread count: " + numberOfThreads + " |--------------------------");
Duration duration = app.demo( numberOfThreads ); // Waits here for the experiment to run to completion.
System.out.println( numberOfThreads + " = " + duration + " total, each: " + duration.dividedBy( numberOfThreads ) );
}
}
// Member fields
final private AtomicInteger count = new AtomicInteger( 0 );
private Duration demo ( final int numberOfThreads )
{
ExecutorService executorService = Executors.newFixedThreadPool( numberOfThreads );
long start = System.nanoTime();
for ( int i = 0 ; i < numberOfThreads ; i++ )
{
executorService.submit( new Task() );
}
executorService.shutdown(); // Ask the executor service to shutdown its backing pool of threads after all submitted tasks are done/canceled/failed.
try { executorService.awaitTermination( 1 , TimeUnit.HOURS ); } catch ( InterruptedException e ) { e.printStackTrace(); } // Tries to force the shutdown after timeout.
Duration elapsed = Duration.ofNanos( System.nanoTime() - start );
return elapsed;
}
class Task implements Runnable
{
@Override
public void run ( )
{
int countSoFar = count.incrementAndGet(); // Thread-safe way to access, increment, and write a counter.
// … add code here to do some kind of work …
System.out.println( "Thread ID " + Thread.currentThread().getId() + " is finishing run after incrementing the countSoFar to: " + countSoFar + " at " + Instant.now() );
}
}
}
我正在研究 Java 多线程并尝试检查多个线程的性能 threads.I 我正在尝试检查多线程是否比单线程更好。 所以,我写了一个代码来限制总和。 当 limit 变大时,它按我预期的方式工作(多线程比单线程快),但当 limit 小到 100000L 时却没有。 这是由于上下文切换吗?下面的代码是否适合检查多线程的性能?
public class MultiThreadingSum {
long count = 0;
static long limit = 1000000000L;
static void compareMultipleThreadToSingleThread(int threadCnt) {
Runnable r = () -> {
MultiThreadingSum mts = new MultiThreadingSum();
long startTime = System.nanoTime();
while(++mts.count<=limit);
long endTime = System.nanoTime();
long estimatedTime = endTime - startTime;
double seconds = estimatedTime / 1000000000.0;
System.out.println(Thread.currentThread().getName()+", elapsed time : "+seconds);
};
for(int i=0; i<threadCnt; i++) {
new Thread(r, "multiThread"+i).start();
}
Runnable r2 = () -> {
MultiThreadingSum mts = new MultiThreadingSum();
long startTime = System.nanoTime();
while(++mts.count<=limit*threadCnt);
long endTime = System.nanoTime();
long estimatedTime = endTime - startTime;
double seconds = estimatedTime / 1000000000.0;
System.out.println(Thread.currentThread().getName()+", elapsed time : "+seconds);
};
new Thread(r2, "singleThread").start();
}
public static void main(String[] args) {
compareMultipleThreadToSingleThread(3);
}
}
这不是一个很好的例子。多线程和单线程解决方案 运行 同时在同一个柜台上。所以实际上你 运行 一个有四个线程的多线程进程。您需要 运行 一个解决方案,直到线程完成并关闭,然后是另一个。最简单的解决方案是 运行 单线程进程作为 main 方法中的简单循环,运行 循环完成后的多线程解决方案。另外,我会有两个单独的计数器,或者,您可以在单线程循环完成后将零分配给计数器
您的代码不会在 运行 单线程实验之前等待 3 线程实验完成。所以你可能会污染你的结果。
您的代码似乎不必要地复杂。我们不能 运行 两个单独的实验,一个有 3 个线程,一个有 1 个线程,分别重用代码吗?
在现代 Java 中,我们很少需要解决 Thread
class。相反,使用添加到 Java 5.
综上所述,也许您的实验应该更像下面这样。
警告:这只是一个非常粗略的剪辑,我没有考虑清楚,我的咖啡因已经耗尽。因此,请深思熟虑地修改此代码。也许我可以在一两天内修改这段代码。
package work.basil.threading;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Loopy
{
public static void main ( String[] args )
{
Loopy app = new Loopy();
List < Integer > inputThreadsLimit = List.of( 1 , 3 , ( Runtime.getRuntime().availableProcessors() - 1 ) );
for ( Integer numberOfThreads : inputThreadsLimit )
{
System.out.println("----------| Experiment for thread count: " + numberOfThreads + " |--------------------------");
Duration duration = app.demo( numberOfThreads ); // Waits here for the experiment to run to completion.
System.out.println( numberOfThreads + " = " + duration + " total, each: " + duration.dividedBy( numberOfThreads ) );
}
}
// Member fields
final private AtomicInteger count = new AtomicInteger( 0 );
private Duration demo ( final int numberOfThreads )
{
ExecutorService executorService = Executors.newFixedThreadPool( numberOfThreads );
long start = System.nanoTime();
for ( int i = 0 ; i < numberOfThreads ; i++ )
{
executorService.submit( new Task() );
}
executorService.shutdown(); // Ask the executor service to shutdown its backing pool of threads after all submitted tasks are done/canceled/failed.
try { executorService.awaitTermination( 1 , TimeUnit.HOURS ); } catch ( InterruptedException e ) { e.printStackTrace(); } // Tries to force the shutdown after timeout.
Duration elapsed = Duration.ofNanos( System.nanoTime() - start );
return elapsed;
}
class Task implements Runnable
{
@Override
public void run ( )
{
int countSoFar = count.incrementAndGet(); // Thread-safe way to access, increment, and write a counter.
// … add code here to do some kind of work …
System.out.println( "Thread ID " + Thread.currentThread().getId() + " is finishing run after incrementing the countSoFar to: " + countSoFar + " at " + Instant.now() );
}
}
}