你只需要運行一個附加線程:
public class Main {
/**
* Delay in milliseconds until finished.
*/
private static final long FINISH_BY = 10000;
/**
* Start with this number.
*/
private static final int START_WITH = 1;
/**
* Delay between eversquare passes in milliseconds.
*/
private static final long DELAY_BETWEEN_PASSES = 50;
/**
* Holds the current result. The "volatile" keyword tells the JVM that the
* value could be changed by another thread, so don't cache it. Marking a
* variable as volatile incurs a *serious* performance hit so don't use it
* unless really necessary.
*/
private static volatile int currentResult = 0;
public static void main(String[] args) {
// create a Thread to run "eversquare" in parallel
Thread eversquareThread = new Thread(new Runnable() {
@Override public void run() {
eversquare(START_WITH, DELAY_BETWEEN_PASSES);
}
});
// make the eversquare thread shut down when the "main" method exits
// (otherwise the program would never finish, since the "eversquare" thread
// would run forever due to its "while" loop)
eversquareThread.setDaemon(true);
// start the eversquare thread
eversquareThread.start();
// wait until the specified delay is up
long currentTime = System.currentTimeMillis();
final long stopTime = currentTime + FINISH_BY;
while (currentTime < stopTime) {
final long sleepTime = stopTime - currentTime;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException ex) {
// in the unlikely event of an InterruptedException, do nothing since
// the "while" loop will continue until done anyway
}
currentTime = System.currentTimeMillis();
}
System.out.println(currentResult);
}
/**
* Increment the value and compute its square. Runs forever if left to its own
* devices.
*
* @param startValue
* The value to start with.
*
* @param delay
* If you were to try to run this without any delay between passes, it would
* max out the CPU and starve any other threads. This value is the wait time
* between passes.
*/
private static void eversquare(final int startValue, final long delay) {
int currentValue = startValue;
while (true) { // run forever (just use "true"; "2==2" looks silly)
currentResult = square(currentValue); // store in the global "currentResult"
currentValue++; // even shorter than "x += 1"
if (delay > 0) {
try { // need to handle the exception that "Thread.sleep()" can throw
Thread.sleep(delay);
} catch (InterruptedException ex) { // "Thread.sleep()" can throw this
// just print to the console in the unlikely event of an
// InterruptedException--things will continue fine
ex.printStackTrace();
}
}
}
}
private static int square(int x) {
return x * x;
}
}
我還要提到的是,「揮發性」關鍵字工程(大多數)原語,因爲任何JVM你會看到這幾天的保證他們將被原子地修改。對象不是這種情況,您需要使用同步塊和鎖以確保它們總是以一致的狀態「看到」。
大多數人也提到,你真的應該不使用的方法本身的關鍵字,並在特定的「鎖定」對象,而不是同步。通常這個鎖對象不應該在你的代碼之外可見。這有助於防止人們錯誤地使用你的代碼,使自己陷入困境,然後試圖責怪你。 :)
爲什麼'while(2 == 2)'而不是'while(true)'?請記住,您可以同步方法內的塊,而不僅僅是整個方法。 –
閱讀併發教程,並嘗試一些:http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html –
@PatriciaShanahan它們具有等同的布爾值,將來會使用true。在三天前開始學習java,你能否再解釋一下你的意思是「你可以在一個方法中同步一個塊,而不僅僅是一個完整的方法」,以及它如何幫助我。 – Michael