[英]Java freeze when not debugging or printing
我創建了一個簡單的最接近點算法應用程序,並帶有用於學校作業的漂亮UI。
問題是,當我停止重新運行算法時,出現了非常奇怪的凍結。 僅當我出於某種原因未調試且未編寫控制台輸出時,才會發生這種情況。
當我單擊按鈕再次運行算法時,第一次運行應該停止計算。 但是由於某種原因,它僅在我調試或寫入控制台時才這樣做,而在其他情況下,它只是完成了計算。 凍結本身非常明顯,因為我正在GUI線程上執行thread.join()
,但是算法沒有中斷的事實有點奇怪。
這是算法類:
public class Bruteforce extends Algorithm
{
public Bruteforce( AlgorithmListener listener )
{
super( listener );
}
public void runAlgorithm()
{
EditablePair pair = new EditablePair();
long startTime = System.currentTimeMillis();
for ( int i = 0; i < pointlist.size() - 1 && keepRunning; i++ )
{
// Uncomment next line or run in debug and freeze doesn't happen
//System.out.print( (keepRunning ? 1 : 0) );
Point pi = pointlist.get( i );
for ( int j = i + 1; j < pointlist.size() && keepRunning; j++ )
{
Point pj = pointlist.get( j );
long d = pi.calculateSquaredDistanceTo( pj );
if ( d < pair.distance || pair.distance == -1 )
{
pair.distance = d;
pair.a = pi;
pair.b = pj;
}
}
}
int calculationtime = (int) ( System.currentTimeMillis() - startTime );
if(!keepRunning)
listener.onCalculated( null , -1 , -1 );
listener.onCalculated( new Pair( pair ) , calculationtime , 0 );
}
}
算法超類:
public abstract class Algorithm implements Runnable
{
public boolean visualizeOutput = false;
protected AlgorithmListener listener;
protected boolean keepRunning;
protected Thread thread;
private ArrayList<Point> tmpList;
protected ArrayList<Point> pointlist;
public Algorithm(AlgorithmListener listener)
{
this.listener = listener;
}
public void process(ArrayList<Point> pointlist)
{
System.out.println("Pre Start 1");
tmpList = pointlist;
System.out.println("Pre Start 2");
listener.onStatusChanged( "Cancelling Previous Run..." );
stopAndJoin();
System.out.println("Pre Start 3");
start();
}
public void start()
{
keepRunning = true;
thread = new Thread(this);
System.out.println("Post Start 1");
thread.start();
System.out.println("Post Start 2");
}
public void run()
{
System.out.println("Pre Run 1");
listener.onStatusChanged( "Copying Point List..." );
this.pointlist = new ArrayList<>(tmpList);
System.out.println("Pre Run 2");
listener.onStatusChanged( "Calculating..." );
System.out.println("Pre Run 3");
runAlgorithm();
System.out.println("Post Run 1");
}
public abstract void runAlgorithm();
public void stop()
{
keepRunning = false;
}
public void stopAndJoin()
{
stop();
if(thread != null)
try
{
thread.join();
}
catch( InterruptedException e )
{
e.printStackTrace();
}
}
}
僅當您在50.000+點上運行並在首次計算開始后再次按下按鈕時,該參數才值得注意
控制台輸出
Pre Start 1
Pre Start 2
Pre Start 3
Post Start 1
Post Start 2
Pre Run 1
Pre Run 2
Pre Run 3
Pre Start 1
Pre Start 2
UI凍結,直到完成計算,然后再次運行
([43768, 37240], [43769, 37240]) Distance = 1
Post Run 1
Pre Start 3
Post Start 1
Post Start 2
Pre Run 1
Pre Run 2
Pre Run 3
([43768, 37240], [43769, 37240]) Distance = 1
Post Run 1
我不知道為什么會這樣以及如何預防。
我自己沒有測試過,但是keepRunning
是這可能是因為您的變量keepRunning
是陳舊的。 如果正在從不同線程訪問此變量,則應真正使它volatile
以確保可以從不同線程正確訪問它。
所以改變這個:
protected boolean keepRunning;
對此:
protected volatile boolean keepRunning;
欲了解更多信息,請看這里 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.