Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8122057

Threadis hanging

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 7u45
    • javafx
    • JavaFX 2

      I had an issue while creating a download manager in JavaFX. I raised my concern in JavaFX OTN Community (https://forums.oracle.com/message/11279428) but the issue is not yet resolved .



      Problem :

      Calling a thread from ExecutorService which executes a thread which download file from the given URL. Code was working fine and I used it to download some sample files.
      Then I added code to find rate of download in the Thread run and print the output(rate=(1024/(end-start))). After adding that code the task is not even running .

      Code :

      FXMLDocumentController.java


      package try3;

      import java.io.File;
      import java.net.MalformedURLException;
      import java.net.URL;
      import java.util.ResourceBundle;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.ThreadFactory;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.event.ActionEvent;
      import javafx.fxml.FXML;
      import javafx.fxml.Initializable;
      import javafx.scene.control.Label;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableView;
      import javafx.scene.control.TextField;
      import javafx.scene.control.cell.ProgressBarTableCell;
      import javafx.scene.control.cell.PropertyValueFactory;
      import javafx.stage.DirectoryChooser;

      /**
       *
       * @author Lijo Jose
       */
      public class FXMLDocumentController implements Initializable {
          
          @FXML
          private Label comment;
          
          
          @FXML private TextField addr;
          
          @FXML TableView <Worker> table;
          
          @FXML TableColumn<Worker,String> colname;
          @FXML TableColumn<Worker,String> colstatus;
          @FXML TableColumn<Worker,Double> colprogress;
          
          private final ObservableList<Worker> list=FXCollections.observableArrayList();
          private String path=new String("");
          
          
          
          @FXML
          private void addButtonAction(ActionEvent event) throws MalformedURLException {
              
               String name=addr.getText().substring(addr.getText().lastIndexOf("/")+1);
              
                    
              
               if(!name.isEmpty()){
                  list.add(new Worker(name,new URL(addr.getText()),path));
                  System.out.println("Added..."+list.size());
                  comment.setText("Added...");
               }
               else
                   comment.setText("Not Added...");
             
             
              
              
              
              
             
              addr.clear();
              
      //// boolean b=list.add(new Worker(new SimpleStringProperty("ABCD"), new URL("http://ww.goole.co")));
      //
      //
      //
      // comment.setText("Added...");
      //
              
             
              
              
              
          }
          
           @FXML
          private void startButtonAction (ActionEvent event){
           
      // ExecutorService service= Executors.newFixedThreadPool(3);
            ExecutorService service= Executors.newFixedThreadPool(2, new ThreadFactory() {

                  @Override
                  public Thread newThread(Runnable r) {
                      Thread t=new Thread(r);
                      t.setDaemon(true);
                      return t;
                      
                  }
              });
      // Worker selected=table.getSelectionModel().getSelectedItem();
               
              
      // System.out.println("Selected :"+selected.getName()+" "+selected.getUrl());
               
              
              
              
              for(Worker w:table.getItems())
                  service.execute(w);
               
                
               
               
          }
          @FXML
          private void stopButtonAction (ActionEvent event){
            Worker selected=table.getSelectionModel().getSelectedItem();
            int index=table.getSelectionModel().getSelectedIndex();
            
            selected.stopTask();
            
           
            
            
            list.set(index, selected);
            
      // table.setItems(list);
            
            table.getColumns().get(0).setVisible(false);
            table.getColumns().get(0).setVisible(true);
            
            System.out.println("Index.."+index);
            
            for(Worker entry:list)
                  System.out.println(entry.getName()+" "+entry.getProgress()+" "+entry.getMessage());
            
            
          }
          
          
          
          @FXML
          private void removeButtonAction(ActionEvent e){
           Worker selected=table.getSelectionModel().getSelectedItem();
            
            list.remove(selected);
            System.out.println("Removed...");
            
            
          }
          
          @FXML
          private void pathButtonAction(ActionEvent e){
              DirectoryChooser chooser= new DirectoryChooser();
              File showDialog = chooser.showDialog(null);
              String temp;
              
              if(showDialog!=null)
              {
                   temp=showDialog.getPath();
                   
                   if(temp.endsWith("\\")){
                     comment.setText(temp);
                     path=temp;
                   }
                   else{
                     comment.setText(temp+"\\");
                     path=temp+"\\";
                   }
                  
              }
          }
          
          
          @Override
          public void initialize(URL url, ResourceBundle rb) {
              // TODO
              
              colname.setCellValueFactory(new PropertyValueFactory<Worker,String>("name"));
              
              
              colprogress.setCellValueFactory(new PropertyValueFactory<Worker,Double>("progress"));
              colprogress.setCellFactory(ProgressBarTableCell.<Worker>forTableColumn());
              
              colstatus.setCellValueFactory(new PropertyValueFactory<Worker,String>("message"));
              
              
              
              
              
              table.setItems(list);
          }
          
      }

      ---------------------------
      Worker.java

      /*
       * To change this license header, choose License Headers in Project Properties.
       * To change this template file, choose Tools | Templates
       * and open the template in the editor.
       */

      package try3;

      import java.io.IOException;
      import java.io.InputStream;
      import java.io.RandomAccessFile;
      import java.net.HttpURLConnection;
      import java.net.URL;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import javafx.concurrent.Task;
      import javafx.scene.control.ProgressIndicator;


      /**
       *
       * @author Lijo Jose
       */
      public class Worker extends Task{

          private String name;
          private URL url;
          
          
          
          private int downloaded=0;
          private RandomAccessFile file;
          private InputStream stream;
          private int size=-1;
          private int status;
          private final int DOWNLOADING=0;
          private final int COMPLETED=1;
          private final int MAX_BUFFER_SIZE=1024*1024;
          private String path;
          private long start,end;
          private float rate;
          

          public Worker(String fname, URL url) {
              this.name = fname;
              this.url = url;
              updateMessage("Not Started..");
          }

          Worker(String fname, URL url, String path) {
              this.name = fname;
              this.url = url;
              this.path=path;
              updateMessage("Not Started..");
           }
          
          
          
          
          @Override
          protected Object call() throws Exception {
              
              
              updateProgress(ProgressIndicator.INDETERMINATE_PROGRESS, 100);
      // Thread.sleep(100);
               
               
      // String temp=url.getFile().substring(url.getFile().lastIndexOf("/")+1);
               System.out.println("Path :"+path+",File Name:"+name);
      // System.out.println("Temp: "+temp);
              try {
                  HttpURLConnection connection=(HttpURLConnection) url.openConnection();
                  connection.setRequestProperty("Range", "bytes="+downloaded+"-");
                  
                  connection.connect();
                  if(connection.getResponseCode()/100!=2){
                      error("Respose Code :"+String.valueOf(connection.getResponseCode()));
                  }
                          
                  int contentLength=connection.getContentLength();
                  
                  if(contentLength<1){
                      error("Content Length :"+String.valueOf(contentLength));
                  }
                  size=contentLength;
                  
                  System.out.println("Size :"+size);
                  
                  
                  
                  file= new RandomAccessFile(path+this.name, "rw");
                  file.seek(downloaded);
                  
                  System.out.println("path :"+path+this.name);
                  stream=connection.getInputStream();
                  
                  while(status==DOWNLOADING){
                      byte[] buffer;
                      if(size-downloaded>MAX_BUFFER_SIZE){
                          buffer=new byte[MAX_BUFFER_SIZE];
                      }
                      else{
                          buffer=new byte[size-downloaded];
                      }
                      
                      start=System.currentTimeMillis();
                      
                      int read=stream.read(buffer);
                      
                      end=System.currentTimeMillis();
                      
                      if(read==-1)
                          break;
             
                      
                      file.write(buffer,0,read);
                      downloaded+=read;
                      

                      
                      
                      System.out.println("Start:"+start+" End :"+end+" Diff :"+(end-start));

                      
                      rate=(1024/(end-start));
                      System.out.println("Rate :"+rate+" KBps");
                      
                      updateMessage("In Progress");
                      updateProgress(downloaded, size);
                  }
                  
                  
                  status=COMPLETED;
                  
                      
                  System.out.println("Downloaded...");
                  updateMessage("Completed..");
                  updateProgress(100, 100);
                          
              } catch (IOException ex) {
                  System.out.println("Error :"+ex.toString());
              }
              finally{
                  try {
                      file.close();
                  } catch (IOException ex) {
                      Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, null, ex);
                      System.out.println("Error: "+ex.toString());
                  }
                  
                  if(stream!=null){
                      try {
                          stream.close();
                      } catch (IOException ex) {
                          System.out.println("Error :"+ex.toString());
                      }
                  }
              }
              return null;
              
              
              
          }

          public void setName(String fileName){
              name=fileName;
          }
            
          public String getName(){
              return name;
          }

          /**
           * @return the url
           */
          public URL getUrl() {
              return url;
          }

          /**
           * @param url the url to set
           */
          public void setUrl(URL url) {
              this.url = url;
          }

          void stopTask() {
              updateMessage("Stopped..");
              try {
                  Thread.sleep(100);
              } catch (InterruptedException ex) {
                  Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, null, ex);
              }
              
          }
          private void error(String err) {
              System.out.println("Error...."+err);
          }
          
      }
      -----------------------------

      Try3.java

      package try3;

      import javafx.application.Application;
      import javafx.fxml.FXMLLoader;
      import javafx.scene.Parent;
      import javafx.scene.Scene;
      import javafx.stage.Stage;

      /**
       *
       * @author Lijo Jose
       */
      public class Try3 extends Application {
          
          @Override
          public void start(Stage stage) throws Exception {
              Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
              
              Scene scene = new Scene(root);
              
              stage.setScene(scene);
              stage.show();
          }

          public static void main(String[] args) {
              launch(args);
          }
          
      }
      -----------------------------------

      FXMLDocument.fxml


      <?xml version="1.0" encoding="UTF-8"?>

      <?import java.lang.*?>
      <?import java.util.*?>
      <?import javafx.scene.*?>
      <?import javafx.scene.control.*?>
      <?import javafx.scene.layout.*?>

      <AnchorPane id="AnchorPane" prefHeight="411.0" prefWidth="387.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="try3.FXMLDocumentController">
        <children>
          <Button fx:id="button" layoutX="239.0" layoutY="23.0" onAction="#addButtonAction" text="Add" />
          <Label id="label" fx:id="comment" layoutX="14.0" layoutY="381.0" minHeight="16.0" minWidth="69.0" prefWidth="186.0" />
          <TextField fx:id="addr" layoutX="14.0" layoutY="23.0" prefWidth="200.0" promptText="Address :" />
          <TableView fx:id="table" layoutX="14.0" layoutY="124.0" prefHeight="220.0" prefWidth="333.0">
            <columns>
              <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="130.0" text="Name" fx:id="colname" />
              <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="118.0" text="Progress" fx:id="colprogress" />
              <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="83.0" text="Status" fx:id="colstatus" />
            </columns>
          </TableView>
          <HBox id="HBox" alignment="CENTER" layoutX="17.0" layoutY="76.0" spacing="20.0">
            <children>
              <Button mnemonicParsing="false" onAction="#startButtonAction" text="Start" />
              <Button disable="true" mnemonicParsing="false" onAction="#stopButtonAction" text="Stop" />
              <Button mnemonicParsing="false" onAction="#removeButtonAction" text="Remove" />
              <Button mnemonicParsing="false" onAction="#pathButtonAction" text="Path" />
            </children>
          </HBox>
        </children>
      </AnchorPane>


            kcr Kevin Rushforth
            duke J. Duke
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: