Java-多线程练习
我要做作业,问题是: 查看此程序,运行它并找到问题,然后修复它 以下是节目:Java-多线程练习,java,multithreading,Java,Multithreading,我要做作业,问题是: 查看此程序,运行它并找到问题,然后修复它 以下是节目: package serie02; import java.util.ArrayList; class S2Es1Timer { private long startTime = -1; private long stopTime = -1; final protected void start() { startTime = System.currentTimeMillis
package serie02;
import java.util.ArrayList;
class S2Es1Timer {
private long startTime = -1;
private long stopTime = -1;
final protected void start() {
startTime = System.currentTimeMillis();
}
final protected void stop() {
stopTime = System.currentTimeMillis();
}
final public long getElapsedTime() {
if (startTime < 0 || stopTime < 0)
return 0;
return stopTime - startTime;
}
}
class S2Es1SharedState {
boolean sharedState = false;
}
class S2Es1Worker implements Runnable {
private static final long START_VALUE = 1000000000;
private final int id;
private final S2Es1Timer timer;
private final S2Es1SharedState state;
private long localCounter = START_VALUE;
public S2Es1Worker(final int id, final S2Es1SharedState state) {
this.id = id;
timer = new S2Es1Timer();
this.state = state;
log("created");
}
@Override
public void run() {
timer.start();
while (--localCounter > 0) {
if (state.sharedState) {
timer.stop();
log("sharedState has already been set by another worker. localCounter: "
+ ((100.0 * localCounter) / START_VALUE)
+ " % from goal");
return;
}
}
// richiedi accesso esclusivo per scrittura
state.sharedState = true;
timer.stop();
log("sharedState has been set");
}
final protected void log(final String s) {
System.out.println(this.getClass().getSimpleName() + id + ": " + s);
}
final protected void logElapseTime() {
log("time: " + timer.getElapsedTime() + " ms");
}
}
public class S2Esercizio1 {
private final static int NUM_WORKERS = 10;
public static void main(final String[] args) {
final S2Es1Timer mainTimer = new S2Es1Timer();
final ArrayList<Thread> threads = new ArrayList<Thread>();
final ArrayList<S2Es1Worker> workers = new ArrayList<S2Es1Worker>();
final S2Es1SharedState myShare = new S2Es1SharedState();
// Crea 10 Workers
for (int i = 0; i < NUM_WORKERS; i++) {
final S2Es1Worker worker = new S2Es1Worker(i, myShare);
workers.add(worker);
threads.add(new Thread(worker));
}
System.out.println("Simulation started");
System.out.println("------------------------------------");
mainTimer.start();
// Fa partire tutte le threads
for (final Thread t : threads)
t.start();
try {
// Attende che tutte le threads terminano
for (final Thread t : threads)
t.join();
} catch (final InterruptedException e) {
/* Unhandled exception */
}
mainTimer.stop();
System.out.println("------------------------------------");
for (final S2Es1Worker worker : workers)
worker.logElapseTime();
System.out.println("Simulation time: " + mainTimer.getElapsedTime()
+ " ms");
System.out.println("Simulation finished");
}
}
我认为这是一个可见性问题,我的意思是当第一个线程完成循环并将共享可变变量sharedState设置为true时,其他线程继续循环,因为它们在缓存cpu中有脏读,我有4个cpu。
所以我能做的唯一一件好事就是用键volatile设置sharedState变量。通过这种方式,每个线程都读取正确的值。我浪费了时间,因为这个值现在由主内存而不是cpu缓存捕获。
另一个解决方案是:使用ReentrantReadWriteLock。
因此,可以通过以下方式写入S2Es1SharedState类:
class S2Es1SharedState {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
boolean sharedState = false;
public boolean getSharedState() {
readLock.lock();
try {
return sharedState;
} finally {
readLock.unlock();
}
}
public void setSharedState() {
writeLock.lock();
try {
this.sharedState = true;
}
finally {
writeLock.unlock();
}
}
}
我认为这个解决方案是可行的,因为锁也提供了一个正确的可见性,但我认为需要花费很多时间,因为这样在循环内部我不使用缓存cpu,而只使用主内存。这次手术需要时间。
我不确定我的分析,出于这个原因,我更愿意问你 一般来说,你的教授需要更新;现在没有人以这种方式使用线程——事实上,自从执行器出现以来,再也没有人使用线程了framework@fge翻译是:请求对writingOK的独占访问权,脱离主题,但你怎么说再次询问?我以为chiedere是想问的?@fge executor下学期,他希望我以这种方式开始,不要问我为什么
class S2Es1SharedState {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
boolean sharedState = false;
public boolean getSharedState() {
readLock.lock();
try {
return sharedState;
} finally {
readLock.unlock();
}
}
public void setSharedState() {
writeLock.lock();
try {
this.sharedState = true;
}
finally {
writeLock.unlock();
}
}
}