Java守护线程的理解笔记

为了体会守护线程的作用,我做了一个下载文件的demo,可以没事用来测测网速什么的,其特性如下

1、一共有三个线程,分别是主线程,下载线程,守护线程

2、主线程启动下载线程和守护线程

3、下载线程连续下载100个文件,如果出现异常自动捕获并进入下一个文件的下载

4、如果下载线程下载某个文件超过了30秒,就认为是超时,而这个超时的检测由守护线程执行

5、如果守护线程发现某个文件下载超时,就停掉下载线程,并想办法另起一个新的下载线程继续下载

首先我们不使用Java设置的守护线程,而是用一个普通线程充当“守护线程”,也就是设置一个计数器,下载成功一个文件就+1,加到100后这个伪“守护线程”就会自我终止,代码如下

package zz.vc.qduedu;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;


public class DownloadTest {

public static long totalDownloadTime;//全部文件共消耗的下载时间
 public static long downloadStartTime;//某个文件下载开始的时间
 public static DownloadThread downloadThread;
 public static int completedFileCount = 0;//下载成功的文件数
 public static final String url = "https://d25hz2nnwuc2tq.cloudfront.net/images/image/cache/data/2016/10/19/1476866804-800x450-1080x608.webp";
 public static final int total_times = 100;
 public static void main(String[] args) throws IOException {
  // TODO Auto-generated method stub
  downloadThread = new DownloadThread();
  downloadThread.start();
  AlxDemonThread demonThread = new AlxDemonThread();
  demonThread.start();
 }
 public static class DownloadThread extends Thread{
  public boolean shouldStop = false;//超时后终结此进程
  public void run() {
   for(int i=completedFileCount;i<total_times;i++){
    if(shouldStop)return;
    try {
     long cost = downloadNow(url, i);
     if(shouldStop)return;
     System.out.println("第"+i+"次耗时"+cost);
     
    } catch (Exception e) {
     // TODO: handle exception
     if(shouldStop)return;
     System.out.println("下载失败");
     e.printStackTrace();
    }
    if(shouldStop)return;
    completedFileCount++;
    totalDownloadTime += System.currentTimeMillis() - downloadStartTime;
    downloadStartTime = 0;
   }
   if(!shouldStop)System.out.println("总耗时=="+totalDownloadTime);
  }
 }
 
 public static class AlxDemonThread extends Thread{
  @Override
  public void run() {
   // TODO Auto-generated method stub
   super.run();
   while (2>1) {
    try {
     Thread.sleep(1000);
//     System.out.println("守护线程还活着");
    } catch (InterruptedException e) {
    }
    if(completedFileCount == total_times)return;
    if(System.currentTimeMillis() - downloadStartTime > 30*1000){
//     System.out.println("第"+alreadyTime+"超时了");
     System.out.println("the "+completedFileCount+" time out of time");
     downloadThread.shouldStop = true;
     downloadThread.interrupt();
     downloadThread = new DownloadThread();
     downloadThread.start();
     completedFileCount++;
     totalDownloadTime += 30*1000;
    }
   }
  }
 }
 
 public static long downloadNow(String strUrl,int times) throws IOException{
  downloadStartTime = System.currentTimeMillis();
  URL url = new URL(strUrl);
  HttpsURLConnection httpURLConnection = (HttpsURLConnection) url.openConnection();
        httpURLConnection.setDoInput(true);
        httpURLConnection.setUseCaches(false);
        httpURLConnection.setRequestMethod("GET");
        httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
        httpURLConnection.setRequestProperty("Charset", "UTF-8");
        httpURLConnection.setRequestProperty("Content-Type","multipart/form-data;boundary=" + "******");
        httpURLConnection.connect();
//        System.out.println("响应码是::"+httpURLConnection.getResponseCode());
        File pictureFile = new File("d:/"+times+".jpg");
        BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
        FileOutputStream outputStream = new FileOutputStream(pictureFile);
        byte[] buffer = new byte[1024];
        int len = 0;
        BufferedOutputStream out = new BufferedOutputStream(outputStream);
        while ((len = bis.read(buffer)) != -1) {
         if(System.currentTimeMillis() - downloadStartTime > 30*1000)throw new RuntimeException("超时");
            out.write(buffer, 0, len);
        }
        out.flush();
        out.close();
        bis.close();
        return System.currentTimeMillis()-downloadStartTime;
 }

}

运行上面的程序,可以在控制台看见每次文件下载的耗时,如果出现了异常,并不会中断子线程,而是会开始下载下一个文件

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1cec03be9ed6aa754429e1e3dda850f7.html