PRivate void searchButton_actionPerformed() { outputTA.setText("Searching for: " + searchTF.getText()); //Broken!! Too mUCh work in the Swing thread String[] results = lookup(searchTF.getText()); outputTA.setText(""); for (int i = 0; i < results.length; i++) { String result = results[i]; outputTA.setText(outputTA.getText() + '/n' + result); } } 假如你運行這段代碼(完整的代碼可以在這兒下載),你會立即發現存在一些問題。圖2顯示了查找運行中的一個屏幕截圖。
private void searchButton_actionPerformed() { outputTA.setText("Searching for: " + searchTF.getText()); //the String[][] is used to allow access to // setting the results from an inner class final String[][] results = new String[1][1]; new Thread() { public void run() { results[0] = lookup(searchTF.getText()); } }.start(); outputTA.setText(""); for (int i = 0; i < results[0].length; i++) { String result = results[0][i]; outputTA.setText(outputTA.getText() + '/n' + result); } } 這種方法有很多問題。注重final String[][] 。這是一個處理匿名內部類和作用域的不得已的替代。基本上,在匿名內部類中使用的,但在外部環繞類作用域中定義的任何變量都需要定義為final。你可以通過創建一個數組來持有變量解決這個問題。這樣的話,你可以創建數組為final的,修改數組中的元素,而不是數組的引用自身。既然我們已經解決這個問題,讓我們進入真正的問題所在吧。圖3顯示了這段代碼運行時發生的情況:
private void searchButton_actionPerformed() { outputTA.setText("Searching for: " + searchTF.getText()); final String[][] results = new String[1][1]; new Thread() { public void run() { //get results. results[0] = lookup(searchTF.getText()) // send runnable to the Swing thread // the runnable is queued after the // results are returned SwingUtilities.invokeLater( new Runnable() { public void run() { // Now we're in the Swing thread outputTA.setText(""); for (int i = 0; i < results[0].length; i++) { String result = results[0][i]; outputTA.setText( outputTA.getText() + '/n' + result); } } } ); } }.start();} 這可以工作,但是這樣做令人非常頭痛。我們不得不對通過匿名線程執行的順序,我們還不得不處理困難的scooping問題。問題并不少見,并且,這只是一個非常簡單的例子,我們已經碰到了作用域,變量傳遞,和執行順序等一系列問題。相像一個更復雜的問題,包含了幾層嵌套,共享的引用和指定的執行順序。這種方法很快就失控了。