因此,就像问题图块一样。我正在尝试学习多线程编程。我有一个尴尬的程序使我理解多线程比常规执行更快。该程序在一个Java文件中具有七个类,一个测试类,三个实现Runnable的类,以及三个常规类。六个类都执行相同的操作,计数到1000万并返回结果。我的问题是使用三个线程来运行的三个类,但是它们没有返回我期望的正确计数。但是,三个常规班都可以。
我真的很感谢任何人都可以帮助我了解它发生的原因!我使用JDK 9和Eclipse 2018-12。
import java.time.Duration;
import java.time.Instant;
class MyMultiThreadExample{
public static void main(String[] args) {
GameOne g1 = new GameOne();
GameTwo g2 = new GameTwo();
GameThree g3 = new GameThree();
Thread thread1 = new Thread(g1);
Thread thread2 = new Thread(g2);
Thread thread3 = new Thread(g3);
Instant start1 = Instant.now();
thread1.start();
thread2.start();
thread3.start();
Instant end1 = Instant.now();
long elapsed = Duration.between(start1, end1).toMillis();
int total = g1.getCount() + g2.getCount() + g3.getCount();
System.out.println("MultiThread running cost " + elapsed + " to count " + total + " times");
GameFour g4 = new GameFour();
GameFive g5 = new GameFive();
GameSix g6 = new GameSix();
Instant start2 = Instant.now();
g4.run();
g5.run();
g6.run();
Instant end2 = Instant.now();
long elapsed2 = Duration.between(start2, end2).toMillis();
int total2 = g3.getCount() + g4.getCount() + g5.getCount();
System.out.println("Sequential running cost " + elapsed2 + " to count " + total2 + " times");
}
}
class GameOne implements Runnable {
int count1 = 0;
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
// System.out.print("Game1 at round " + count + " now");
count1++;
}
}
public int getCount() {
System.out.println("GameOne counts " + count1);
return count1;
}
}
class GameTwo implements Runnable {
int count2 = 0;
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
// System.out.print("Game2 at round " + count + " now");
count2++;
}
}
public int getCount() {
System.out.println("GameTwo counts " + count2);
return count2;
}
}
class GameThree implements Runnable {
int count3 = 0;
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
// System.out.print("Game3 at round " + count + " now");
count3++;
}
}
public int getCount() {
System.out.println("GameThree counts " + count3);
return count3;
}
}
class GameFour {
int count4 = 0;
public void run() {
for (int i = 0; i < 10000000; i++) {
// System.out.print("Game3 at round " + count + " now");
count4++;
}
}
public int getCount() {
System.out.println("GameFour counts " + count4);
return count4;
}
}
class GameFive {
int count5 = 0;
public void run() {
for (int i = 0; i < 10000000; i++) {
// System.out.print("Game3 at round " + count + " now");
count5++;
}
}
public int getCount() {
System.out.println("GameFive counts " + count5);
return count5;
}
}
class GameSix {
int count6 = 0;
public void run() {
for (int i = 0; i < 10000000; i++) {
// System.out.print("Game3 at round " + count + " now");
count6++;
}
}
public int getCount() {
System.out.println("GameFive counts " + count6);
return count6;
}
}
答案 0 :(得分:0)
您忘了调用thread.join()
了-这要等到线程完成执行为止。
否则,您正在执行中间读取counter
。
您的代码应为:
thread1.start()
thread2.start()
thread3.start()
thread1.join()
thread2.join()
thread3.join()
此外,您所有的类都可以压缩为一个class Game
:
class Game implements Runnable {
String name;
int count = 0;
public Game(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
// System.out.print(name + " at round " + count + " now");
count++;
}
}
public int getCount() {
System.out.println(name + " counts " + count);
return count;
}
}
每个都有自己的计数器,您可以通过调用run()
在一个线程或同一线程中运行它们-您的main方法除实例化之外,大部分保持不变。可以像这样实例化它们:
Game g1 = new Game("GameOne");
Game g2 = new Game("GameTwo");
Game g3 = new Game("GameThree");
Game g4 = new Game("GameFour");
Game g5 = new Game("GameFive");
Game g6 = new Game("GameSix");
答案 1 :(得分:0)
我有一个尴尬的程序让我理解多线程比常规执行更快。
重要的是要了解并非总是如此。只有长时间运行的任务可以并行运行时,才应使用多个线程。如果您的任务很短,则几乎可以肯定,通过在单个线程上运行,它们会更快地运行,因为在线程之间创建专门的同步会产生开销。
这样一来,您实际上并没有在此处测量正确的时间。
调用Thread.start()
时,它将与函数中的代码并行运行相关的Runnable
。
要让线程继续运行直到完成,必须调用Thread#join()
:
thread1.start();
thread2.start();
thread3.start();
// all 3 Threads may be running now, but maybe not even started!
// let's wait for them to finish running by joining them
thread1.join();
thread2.join();
thread3.join();
这是最简单的等待方式...但是还有其他一些,这是一个复杂的话题。
您还可能会遇到麻烦,因为您的任务处于可变状态(count
变量),并且需要仔细管理来自不同线程的更改的可见性(例如,您可以使其变得易变,因此更新是刷新到其他线程。
要了解有关Java并发的更多信息,建议您阅读有关它的内容。 Baeldung教程非常出色。