Java:为什么线程不会终止

时间:2016-01-05 09:48:38

标签: java multithreading

我不明白为什么我的简单程序中的线程总是无法终止。 我认为这是一个简单的问题,但我不明白为什么。我认为一个简单的exec.shutdown();应该关闭我的Threadpool而没有try和catch for exec.shutdownNow();但大坝不确定。

class 1:test(实现一个运行Threadpool的类)

public class test {


 public static void main(String[] args) throws InterruptedException{

    ExecServicrunnen x = new ExecServicrunnen();

    x.runningThreads();
    Thread.sleep(10000);
    x.getThreadtoStop();
 }
}

第2课:ExecServicerunnen(使用MyTask()实现一个Threadpool作为Runnables)

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


public class ExecServicrunnen {

private volatile boolean solange = true;


 public void runningThreads(){
    ExecutorService exec = Executors.newFixedThreadPool(5);

    while(solange){
        exec.execute(new myTask());


    }
    exec.shutdown();
    try{
        if(!exec.awaitTermination(60, TimeUnit.SECONDS)){
            exec.shutdownNow();
        }
    } catch ( InterruptedException e){
        e.printStackTrace();
        exec.shutdownNow();
            }
 }

 public void getThreadtoStop(){
    solange = false;
 }
}

第3课:myTask(只是等待一段时间)

public class myTask implements Runnable{

public void run() {

// doSomething

try {
    Thread.sleep(10000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

}

程序始终无法终止。

1 个答案:

答案 0 :(得分:4)

死锁。

import java.io.IOException; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; public class FareCrd extends Activity { String image_url="http://movito.nervov.com/img/ace-hd.png"; String[] mString ={"http://movito.nervov.com/img/ace-hd.png", "http://movito.nervov.com/img/Movito_Logo_M.png"}; JSONArray jsonary; ListView list; private Activity activity; private String[] data; private static View inflater=null; //private String[] mStrings={"http://movito.nervov.com/img/ace-hd.png"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fare_crd); list=(ListView)findViewById(R.id.farelist); new ServConn().execute(); } private void parsedata(String data){ //System.out.println(data); try { JSONObject json = new JSONObject(data); jsonary = json.getJSONArray("data"); ListView list = (ListView) findViewById(R.id.farelist); list.setAdapter(new DriverOrderList(getApplicationContext(), R.layout.farecrd, new JSONObject[jsonary.length()])); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private class DriverOrderList extends ArrayAdapter<JSONObject> { int listViewResource; public DriverOrderList(Context context, int resource, JSONObject[] s) { super(context, resource, s); listViewResource = resource; } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(listViewResource, parent, false); ImageLoader imgLoader = new ImageLoader(getApplicationContext()); JSONObject rowdata = new JSONObject(); int loader = R.drawable.stub; try { rowdata = jsonary.getJSONObject(position); System.out.println(rowdata); ImageLoader imgLoader1 = new ImageLoader(getApplicationContext()); ImageView img=(ImageView) row.findViewById(R.id.imgid); imgLoader.DisplayImage(image_url, loader, img); TextView nameTxt = (TextView) row.findViewById(R.id.truckname); TextView idTxt = (TextView) row.findViewById(R.id.id); TextView minrttv =(TextView) row.findViewById(R.id.minimumRate); TextView kmrttxt =(TextView) row.findViewById(R.id.kilometerRate); TextView mindurtv=(TextView) row.findViewById(R.id.minimumDuration); TextView freewatintim = (TextView) row.findViewById(R.id.freeWaitingTime); TextView minuterttxt =(TextView) row.findViewById(R.id.minuteRate); TextView watingchrttv =(TextView)row.findViewById(R.id.waitingCharge); double freewt=(Double) rowdata.get("freeWaitingTime"); double kmratetxt=(Double) rowdata.get("kilometerRate"); double mindurtxt=(Double) rowdata.get("minimumDuration"); double mindur= mindurtxt/60; double minkmrttxt=(Double) rowdata.get("minimumKilometer"); double minrttxt=(Double) rowdata.get("minimumRate"); double mintrate=(Double) rowdata.get("minuteRate"); double minutrat=mintrate/60; double watingchrtxt=(Double) rowdata.get("waitingCharge"); double waitchgunittxt=(Double) rowdata.get("waitingChargeUnit"); nameTxt.setText(rowdata.getString("truckModel")); minrttv.setText("Rs."+minrttxt+" /-"); kmrttxt.setText("Rs."+kmratetxt+"/km after "+minkmrttxt+"km"); mindurtv.setText("first"+mindur+"hr and "+minkmrttxt+"km"); //minuterttxt.setText(minutrat+"/-"); freewatintim.setText("first "+freewt+"min free"); watingchrttv.setText("RS"+watingchrtxt+"after every "+waitchgunittxt+"min"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return row; } } private class ServConn extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { // TODO Auto-generated method stub System.out.println("do in backgrnd"); HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet("http://movito.nervov.com/v1/trucks/miniTruckCategories"); httpget.setHeader(HTTP.CONTENT_TYPE, "application/json"); String replyString = ""; try { HttpResponse response = httpclient.execute(httpget); replyString = EntityUtils.toString(response .getEntity()); } catch (ClientProtocolException e) { System.out.println("ex: " + e); } catch (IOException e) { System.out.println("e: " + e); } return replyString; } @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub super.onPostExecute(result); System.out.println(result); result = "{\"data\":"+result+"}"; parsedata(result); } @Override protected void onPreExecute() {} @Override protected void onProgressUpdate(Void... values) {} } } 在调用x.runningThreads();之前未返回,但x.getThreadtoStop();仅在x.getThreadtoStop();返回后调用。 Voilà,线程永远不会停止。

错误是x.runningThreads();在主线程内运行同步而不是在自己的线程中运行。在等待信号终止时,主线程无法向自身发送终止信号。

在不改变代码结构的情况下,您可以使用另一个线程解决此问题,例如:

runningThreads()

-

public class ExecServicrunnen implements Runnable {

  private volatile boolean solange = true;

  // Rename runningThreads() to run():
  @Override
  public void run() {
    // The former code of runningThreads() here...
  }

}

顺便说一下,在大多数情况下,布尔public class test { public static void main(String[] args) throws InterruptedException{ ExecServicrunnen x = new ExecServicrunnen(); // Have ExecServicrunnen run in its own thread: new Thread( x ).start(); Thread.sleep(10000); x.getThreadtoStop(); } } 逻辑应该通过Thread.interrupt()Thread.currentThread().isInterrupted()来实现。