启动两个线程在同一时间,但避免使用加入后,这对Android程序这对、线程、两个、时间

2023-09-04 03:59:02 作者:陪妳走到世界終結

我已经开始在同一时间,我下载了一些数据包Android程序两个线程。

  SERVERIP = WifiServer;
螺纹thread22 =新主题(新CallDownloader(fileToReceive,SERVERIP,WifiServer,MobileServer));
thread22.start();
SERVERIP = MobileServer;
螺纹thread23 =新主题(新CallDownloader(fileToReceive,SERVERIP,WifiServer,MobileServer));
thread23.start();
 

我想从两个服务器在同一时间下载一些文件。 如果我每一个线程下使用thread.joim();

  SERVERIP = WifiServer;
        螺纹thread22 =新主题(新CallDownloader(fileToReceive,SERVERIP,WifiServer,MobileServer));
        thread22.start();
    thread22.join();
 SERVERIP = MobileServer;
        螺纹thread23 =新主题(新CallDownloader(fileToReceive,SERVERIP,WifiServer,MobileServer));
        thread23.start();
         thread23.join();
 

在code不平行,但序列化。我不希望这样。我知道,联接等待完成第一和之后继续到其他

jerikc的个人页面 OSCHINA

当我拿出的Thread.join();其下载任何事情,而不是我想要下载。与仅使用第一线程,它是不会的第二

我怎么能避免加盟? 因为我需要线程调用连接。 如果你需要更多的细节告诉我把。

下面是主要的code。

 问答LT;字符串> fileparts =新的LinkedList<字符串>();

    时间= SystemClock.currentThreadTimeMillis();
    长的时间2 = System.currentTimeMillis的();

    开始时间=时间2;


    INT intnumbOfChunks =的Integer.parseInt(numbOfChunks);
    intnumbOfChunks = 250;

    的for(int i = 0; I< intnumbOfChunks;我++){

        fileToClaim =;
        fileToClaim =bigbang.mp4;
        fileToClaim =的String.Format(%s.part%06D,fileToClaim,我);

        fileparts.add(fileToClaim);

    }

 INT I = 0;



 而(!fileparts.isEmpty()){
fileToReceive = fileparts.peek();

SERVERIP = WifiServer;
                螺纹thread22 =新主题(新CallDownloader(fileToReceive,SERVERIP,WifiServer,MobileServer));
                thread22.start();
                thread22.start();
                尝试 {
                    thread22.join();
                }赶上(InterruptedException异常E){
                    // TODO自动生成的catch块
                    e.printStackTrace();
                }
                SERVERIP = MobileServer;
                螺纹thread23 =新主题(新CallDownloader(fileToReceive,SERVERIP,WifiServer,MobileServer));
                thread23.start();
                尝试 {
                    thread22.join();
                }赶上(InterruptedException异常E){
                    // TODO自动生成的catch块
                    e.printStackTrace();
                }
螺纹thread3 =新主题(新加入(fileToReceive));
                thread3.start();
                尝试 {
                    thread3.join();
                }赶上(InterruptedException异常E){
                    // TODO自动生成的catch块
                    e.printStackTrace();
                }


                fileparts.remove();}
 

下载器线程

 公共类下载{

    最后弦乐fileToReceive;

    布尔fileDownloaded = FALSE;
    插座ClientSocket的;

    公共下载(字符串fileToReceive){

        this.fileToReceive = fileToReceive;


    }

    公共无效下载(字符串SERVERIP){
        //套接字ClientSocket的= NULL;
        尝试 {
            的System.out.println(kanw与我联系TI PORTA 3248);
            ClientSocket的=新的Socket(SERVERIP,3248);
            的System.out.println(egine我sundesi我TI PORTA 3248);
            的System.out.println(stelnw为+ fileToReceive);

            BufferedWriter将BuffWriter =新的BufferedWriter(
                    新OutputStreamWriter(clientSocket.getOutputStream()));
            BuffWriter.write(fileToReceive +\ N);
            BuffWriter.flush();
            的System.out.println(esteila为+ fileToReceive);
            InputStream的是= clientSocket.getInputStream();

            文件根= Environment.getExternalStorageDirectory();
            的System.out.println(dimiourgo到fakelo VID);
            文件DIR =新的文件(root.getAbsolutePath()+/ VID /);
            //文件DIR =新的文件(root.getAbsolutePath());
            dir.mkdirs();
            的System.out.println(arxizw锡lipsei TOU块);
            byte []的longBytes =新的字节[8]。
            的readFully(ClientSocket的,longBytes);
            ByteBuffer的BB = ByteBuffer.wrap(longBytes);
            长文件长度= bb.getLong();
            的System.out.println(apothikeusi arxeiou);
            // 保存
            @燮pressWarnings(资源)
            FileOutputStream中F =新的FileOutputStream(新建文件(目录,
                    fileToReceive));

            byte []的缓冲区=新的字节[1024];
            INT LEN1 = 0;
            INT的ReadBytes = 0;
            而((LEN1 = is.​​read(缓冲液))大于0){
                f.write(缓冲液,0,LEN1);
                的ReadBytes + = LEN1;

            }

            如果(的ReadBytes ==文件长度){
                this.fileDownloaded = TRUE;
            }
            的System.out.println(接收文件+ fileToReceive);

            的System.out.println(文件:收到);

        }赶上(IOException异常前){
            的System.out.println(客户停止);
            ex.printStackTrace();

        } 最后 {
            尝试 {
                如果(ClientSocket的空=&安培;!&安培;!clientSocket.isClosed()){
                    clientSocket.close();
                }
            }赶上(IOException异常E){
                e.printStackTrace();
            }
        }
    }

    私人无效的readFully(插座ClientSocket的,byte []的缓冲区)
            抛出IOException异常{
        的System.out.println(的readFully);
        InputStream中的InputStream = clientSocket.getInputStream();
        诠释剩余= buffer.length;
        INT读= 0;
        而(剩余&0){

            读= inputStream.read(缓冲区,buffer.length  - 剩下的,剩下的);

            如果(读< 0){
                抛出新IOException异常();
            }
            剩下的 -  =读取;
        }
        的System.out.println(退出);
    }


    公共布尔IsDownloaded(){

        返回this.fileDownloaded;
    }


}
 

CallDownloader类是线程

 公共无效的run(){


        的System.out.println(连接头+ SERVERIP);
        下载D =新的下载(fileToReceive);
        // Downloader1 D1 =新Downloader1(fileToReceive);
        d.download(SERVERIP);
}
 

解决方案

如果线程同时运行,也没有办法,以确保该文件将在任何特定的顺序接收......只是他们将被接收。一旦线程结束一切,它是安全的假设所有的文件将是present。

  //调用start()在所有的线程之前加入()使它们并行工作。

    SERVERIP = WifiServer;

    螺纹thread22 =新主题(新CallDownloader(fileToReceive,SERVERIP,WifiServer,MobileServer));
    thread22.start();

    SERVERIP = MobileServer;

    螺纹thread23 =新主题(新CallDownloader(fileToReceive,SERVERIP,WifiServer,MobileServer));
    thread23.start();

    //这些文件全部线程同时下载了。

    //这个code等待所有的线程来完成。
    thread23.join();
    thread22.join();

    //在这一点上是安全的假设所有文件已下载。附加每个块的文件现在一起得到整个文件。
 

i have two threads starting at the same time in my android program for downloading some packets.

ServerIP = WifiServer;
Thread thread22 = new Thread (new CallDownloader(fileToReceive, ServerIP, WifiServer, MobileServer));
thread22.start();
ServerIP = MobileServer;
Thread thread23 = new Thread (new CallDownloader(fileToReceive, ServerIP, WifiServer, MobileServer));
thread23.start();

i want to download some files from two servers at the same time. if i use under every thread the thread.joim();

 ServerIP = WifiServer;
        Thread thread22 = new Thread (new CallDownloader(fileToReceive, ServerIP, WifiServer, MobileServer));
        thread22.start();
    thread22.join();
 ServerIP = MobileServer;
        Thread thread23 = new Thread (new CallDownloader(fileToReceive, ServerIP, WifiServer, MobileServer));
        thread23.start();
         thread23.join();

the code is not parallel but serialized. and i don't want this. I know that join is waiting to finish the first and after continue to the other.

when i take out the thread.join(); its downloading whatever it wants and not what i want to download. and is using only the first thread and it isn't going to the second.

how i can avoid the join? because i need thread to call the connection. if you need more details tell me to put.

here is the main code.

Queue<String> fileparts = new LinkedList<String>();

    Time = SystemClock.currentThreadTimeMillis();
    long Time2 = System.currentTimeMillis();

    StartTime = Time2;


    int intnumbOfChunks = Integer.parseInt(numbOfChunks);
    intnumbOfChunks = 250;

    for (int i = 0; i < intnumbOfChunks; i++) {

        fileToClaim = "";
        fileToClaim = "bigbang.mp4";
        fileToClaim = String.format("%s.part%06d", fileToClaim, i);

        fileparts.add(fileToClaim);

    }

 int i=0;



 while (!fileparts.isEmpty()) {
fileToReceive = fileparts.peek();

ServerIP = WifiServer;
                Thread thread22 = new Thread (new CallDownloader(fileToReceive, ServerIP, WifiServer, MobileServer));
                thread22.start();
                thread22.start();
                try {
                    thread22.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                ServerIP = MobileServer;
                Thread thread23 = new Thread (new CallDownloader(fileToReceive, ServerIP, WifiServer, MobileServer));
                thread23.start();
                try {
                    thread22.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
Thread thread3 = new Thread(new Join(fileToReceive));
                thread3.start();            
                try {
                    thread3.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }


                fileparts.remove();}

the downloader thread is

public class Downloader {

    final String fileToReceive;

    boolean fileDownloaded = false;
    Socket clientSocket;

    public Downloader(String fileToReceive) {

        this.fileToReceive = fileToReceive;


    }

    public void download(String ServerIP) {
        //Socket clientSocket = null;
        try {
            System.out.println("kanw connect me ti porta 3248");
            clientSocket = new Socket(ServerIP, 3248);
            System.out.println("egine i sundesi me ti porta 3248");
            System.out.println("stelnw to " + fileToReceive);

            BufferedWriter BuffWriter = new BufferedWriter(
                    new OutputStreamWriter(clientSocket.getOutputStream()));
            BuffWriter.write(fileToReceive + "\n");
            BuffWriter.flush();
            System.out.println("esteila to " + fileToReceive);
            InputStream is = clientSocket.getInputStream();

            File root = Environment.getExternalStorageDirectory();
            System.out.println("dimiourgo to fakelo vid ");
            File dir = new File(root.getAbsolutePath() + "/vid/");
            // File dir = new File (root.getAbsolutePath());
            dir.mkdirs();
            System.out.println("arxizw tin lipsei tou chunk");
            byte[] longBytes = new byte[8];
            readFully(clientSocket, longBytes);
            ByteBuffer bb = ByteBuffer.wrap(longBytes);
            long fileLength = bb.getLong();
            System.out.println("apothikeusi arxeiou");
            // save
            @SuppressWarnings("resource")
            FileOutputStream f = new FileOutputStream(new File(dir,
                    fileToReceive));

            byte[] buffer = new byte[1024];
            int len1 = 0;
            int readBytes = 0;
            while ((len1 = is.read(buffer)) > 0) {
                f.write(buffer, 0, len1);
                readBytes += len1;

            }

            if (readBytes == fileLength) {
                this.fileDownloaded = true;
            }
            System.out.println("Receiving the file " + fileToReceive);

            System.out.println("File Recieved");

        } catch (IOException ex) {
            System.out.println("Client stopped");
            ex.printStackTrace();

        } finally {
            try {
                if (clientSocket != null && !clientSocket.isClosed()) {
                    clientSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void readFully(Socket clientSocket, byte[] buffer)
            throws IOException {
        System.out.println("readfully");
        InputStream inputStream = clientSocket.getInputStream();
        int remaining = buffer.length;
        int read = 0;
        while (remaining > 0) {

            read = inputStream.read(buffer, buffer.length - remaining,  remaining);

            if (read < 0) {
                throw new IOException();
            }
            remaining -= read;
        }
        System.out.println("exit");
    }


    public boolean IsDownloaded() {

        return this.fileDownloaded;
    }


}

CallDownloader class is the thread

public void run() {


        System.out.println("connecting tou "+ServerIP);
        Downloader d = new Downloader(fileToReceive);
        //Downloader1 d1 = new Downloader1(fileToReceive);
        d.download(ServerIP);
}

解决方案

If the threads are running concurrently, there is no way to be sure that the files will be received in any specific order... only that they will be received. Once all of the threads end, it is safe to assume all of the files will be present.

    //Calling start() on all of the threads before join() causes for them to work concurrently.        

    ServerIP = WifiServer;

    Thread thread22 = new Thread (new CallDownloader(fileToReceive, ServerIP, WifiServer, MobileServer));
    thread22.start();

    ServerIP = MobileServer;

    Thread thread23 = new Thread (new CallDownloader(fileToReceive, ServerIP, WifiServer, MobileServer));
    thread23.start();

    //The files are all downloading concurrently in threads now.

    //This code waits for all of the threads to finish.
    thread23.join();
    thread22.join();

    //At this point it is safe to assume all of the files have been downloaded.  Append each chunk file together now to get the entire file.