java – 多线程总是比单线程产生更好的性能?
我知道答案是否定的,这里是一个例子
Why single thread is faster than multithreading in Java?.
因此,当处理线程中的任务是微不足道的时候,创建线程的成本会比分配任务创造更多的开销.这是一个单线程比多线程快的情况. 问题 >有更多的情况下单线程将比多线程快吗? 虽然这个问题是java的标签,但也欢迎讨论超越Java. 解决方法
这是一个非常好的问题,关于线程及其与实际工作的链接,意味着可用的物理CPU及其内核和超线程.
>如果您的CPU有多个核心可用,多线程可能会让您并行执行此操作.所以在一个理想的世界,例如如果您的CPU有4个核心可用,并且您的算法工作真正并行,那么使用4个线程可能会增加一些素数的4倍. 所以我从高度parrallel多线程中学到的经验是: >如果可能,使用单线程,无共享进程来提高效率 这里有一个小程序(javafx)来玩.它: >分配一个100.000.000大小的字节数组,填充随机字节 使用MacPro(4核)导致: >运行一个线程,count(0,1)需要1326ms计数所有399993625位 改变计数方式,例如增加一个共同的整数(AtomicInteger或synchronized)会大大改变许多线程的性能. public class MulithreadingEffects extends Application { static class ParallelProgressBar extends ProgressBar { AtomicInteger myDoneCount = new AtomicInteger(); int myTotalCount; Timeline myWhatcher = new Timeline(new KeyFrame(Duration.millis(10),e -> update())); BooleanProperty running = new SimpleBooleanProperty(false); public void update() { setProgress(1.0*myDoneCount.get()/myTotalCount); if (myDoneCount.get() >= myTotalCount) { myWhatcher.stop(); myTotalCount = 0; running.set(false); } } public boolean isRunning() { return myTotalCount > 0; } public BooleanProperty runningProperty() { return running; } public void start(int totalCount) { myDoneCount.set(0); myTotalCount = totalCount; setProgress(0.0); myWhatcher.setCycleCount(Timeline.INDEFINITE); myWhatcher.play(); running.set(true); } public void add(int n) { myDoneCount.addAndGet(n); } } int mySize = 100000000; byte[] inData = new byte[mySize]; ParallelProgressBar globalProgressBar = new ParallelProgressBar(); BooleanProperty iamReady = new SimpleBooleanProperty(false); AtomicInteger myCounter = new AtomicInteger(0); void count(int start,int step) { new Thread(""+start){ public void run() { int count = 0; int loops = 0; for (int i = start; i < mySize; i+=step) { for (int m = 0x80; m > 0; m >>=1) { if ((inData[i] & m) > 0) count++; } if (loops++ > 99) { globalProgressBar.add(loops); loops = 0; } } myCounter.addAndGet(count); globalProgressBar.add(loops); } }.start(); } void pcount(Label result,int n) { result.setText("("+n+")"); globalProgressBar.start(mySize); long start = System.currentTimeMillis(); myCounter.set(0); globalProgressBar.runningProperty().addListener((p,o,v) -> { if (!v) { long ms = System.currentTimeMillis()-start; result.setText(""+ms+" ms ("+myCounter.get()+")"); } }); for (int t = 0; t < n; t++) count(t,n); } void testParallel(VBox box) { HBox hbox = new HBox(); Label result = new Label("-"); for (int i : new int[]{1,2,4,8}) { Button run = new Button(""+i); run.setOnAction( e -> { if (globalProgressBar.isRunning()) return; pcount(result,i); }); hbox.getChildren().add(run); } hbox.getChildren().addAll(result); box.getChildren().addAll(globalProgressBar,hbox); } @Override public void start(Stage primaryStage) throws Exception { primaryStage.setTitle("ProgressBar's"); globalProgressBar.start(mySize); new Thread("Prepare"){ public void run() { iamReady.set(false); Random random = new Random(); random.setSeed(4711); for (int i = 0; i < mySize; i++) { inData[i] = (byte)random.nextInt(256); globalProgressBar.add(1); } iamReady.set(true); } }.start(); VBox box = new VBox(); Scene scene = new Scene(box,400,80,Color.WHITE); primaryStage.setScene(scene); testParallel(box); GUIHelper.allowImageDrag(box); primaryStage.show(); } public static void main(String[] args) { launch(args); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Java – 使用Eclipse在Google App Engine上使用Scala
- java – Optional.ofNullable和方法链接
- java – 显式锁是否自动提供内存可见性?
- 如何使用Spring AOP的通知类型及创建通知
- java – 将ThreadLocal与包含静态成员的现有类一起使用
- java – 如何仅使用for循环生成奇数
- java – 如何改进这个单例?
- Java线程之线程同步synchronized和volatile详解
- java – 你可以批量选择IntelliJ IDEA中的引号之间的文本吗
- java – ZonedDateTime作为Spring REST RequestMapping中的