Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java(Android)多线程进程_Java_Android_Multithreading_Threadpoolexecutor_Blockingqueue - Fatal编程技术网

Java(Android)多线程进程

Java(Android)多线程进程,java,android,multithreading,threadpoolexecutor,blockingqueue,Java,Android,Multithreading,Threadpoolexecutor,Blockingqueue,我正在开发一个应用程序(Matt的traceroutewindows版本),它创建多线程,每个线程都有自己的进程(执行ping命令)线程池执行器在一段时间后关闭所有线程(例如10秒) ThreadPoolExecutor使用阻塞队列(在任务执行之前保留任务) 现在,如果我创建多个线程,比如说一个循环中有500多个线程,并在池执行器中执行 执行线程 PingThread thread = new PingThread(params); poolExecutor.execute(thread);

我正在开发一个应用程序(Matt的traceroutewindows版本),它创建多线程,每个线程都有自己的进程(执行ping命令)<代码>线程池执行器在一段时间后关闭所有线程(例如10秒)

ThreadPoolExecutor
使用阻塞队列(在任务执行之前保留任务)

现在,如果我创建多个线程,比如说一个循环中有500多个线程,并在池执行器中执行

执行线程

PingThread thread = new PingThread(params);
poolExecutor.execute(thread);
我知道,
LinkedBlockingQueue
在任务执行之前保存任务。每个线程的进程最长需要200到400ms,但通常不到10ms

我在做什么

for (int iteration = 1; iteration <= 50/*configurable*/; iteration++) {

    for (int index = 0; index < 10/*configurable*/; index++) {
        PingThread thread = new PingThread(someParams);
        poolExecutor.execute(thread);
    }

    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        Logger.error(false, e);
    }   
}

for(int iteration=1;iteration我不确定这是否是导致所有问题的原因,但您正在创建许多不必要的线程

你应该换一个

private class PingThread extends Thread {
与:

private class PingThread implements Runnable {
或者(使用更合适的名称):


i、 e.提交给
执行者的任务不应该是线程本身。它可以工作,因为
线程
实现
可运行的
,但您正在浪费它。

线程创建一个新的唯一对象,而可运行的则允许所有线程共享一个对象。因此,在尝试ltithread,而使用Runnable:

class RunnableDemo implements Runnable {
    private Thread thread;
    String threadName="My thread";
    public void run() {
        //do your code from here 'logic'
        System.out.println("Threading is Running");
        try {
            for(int i = 4; i > 0; i--) {
                System.out.println("Thread: "+threadName +" "+ i);
                // Let the thread sleep for a while.
                Thread.sleep(50); //sleep your content for xx miliseconds
            }
        } catch (InterruptedException e) {
            System.out.println("Thread " +  threadName + " interrupted.");
        }
        System.out.println("Thread " +  threadName + " exiting.");
        //finish your work here 
    }

    public void start () {
        System.out.println("Starting " +  threadName );
        if (thread == null) {
            thread = new Thread (this);
            thread.start (); //This will call your run methods of Runnable
        }
    }
}
//test your thread from here
public class TestThread {
    public static void main(String args[]) {
        RunnableDemo R1 = new RunnableDemo( "Thread-1");
        R1.start();

        RunnableDemo R2 = new RunnableDemo( "Thread-2");
        R2.start();
    }   
}
观察: 在使用相同的代码创建并观察独立java应用程序(日志)后,我了解到以下几点:

  • 不知何故,android操作系统架构和/或处理器限制了线程的数量
  • LinkedBlockingQueue
    在任务执行之前保存任务,所以如果我们有一个长队列,队列中的线程将不得不等待更长时间
  • 增加/Dynamic
    corePoolSize
    maxPoolSize
    也是这样做的,他们在队列中添加了线程
  • 应用程序使用了4-6%的CPU,所以我们不能说CPU过载或利用了全部应用程序资源,但当应用程序进入后台(GUI或其他相关操作系统和/或基于应用程序的线程可能停止或中断)时,CPU使用率下降到0-3%

解决方案: 对于50次迭代和10次内部创建500个线程,现在我做了两件事:

  • 增加
    线程。睡眠时间(毫秒)
    并进行一些计算
  • 减少每次迭代的线程数。我现在创建了10个线程
    Math.ceil((double)10/3)=3个
    ,因此我们有3个顺序
    PingUtils.executeingRequest(pingRequest)
    对于每个线程,即
    3*3=9
    仍然为1,因此我们将为最后一个请求创建一个单独的线程。对于每个迭代,我现在创建4个线程,而不是创建10个线程
  • 使用这种方法,我现在有200个线程,而不是500个线程,解决了这个问题

这是一个很好的实践,我使用线程来识别哪些线程需要时间来执行,只是为了识别,我会将代码恢复到可运行状态,但我认为这不会解决我的问题,是的,每个线程创建唯一的对象,而可运行状态将相同的对象共享给多个线程。您可以创建
线程实例(直接或通过扩展)您自己,或使用
执行器
,但两者都是浪费(很多)资源。
ThreadPoolExecutor
使用自己的线程,而不是您提供给它的线程。换句话说,
PingThread
只是一个非常重要的
Runnable
实现。如果您增加线程池大小(例如16-->32或48),我会尝试让您知道会发生什么?ping通常不是CPU密集型任务,池中的线程大部分时间都在等待网络。我尝试了GrowtBeforeQueueThreadPoolExecutor,正如上面的帖子所建议的那样,但到目前为止还没有发现,在我的帖子中,CPU使用率在4-6%或低于10%之间,但当应用程序转到后台时,CPU使用率下降到0-2%,所有任务都已完成Imin你不需要为每个子进程运行一个线程,所以我建议你从那里开始。另外,你的应用程序的核心特性是Ping和路径跟踪,你应该考虑在进程中实现和执行这些任务。如果你异步地这样做,你不需要线程或子进程,并且你可以控制CcCurela。这一切都将显著提高应用程序的性能、可扩展性以及在规格较低(CPU速度、内存、网络带宽等)的设备上的电池使用率它的客户端要求在单独的线程中ping每个ip?您所说的进程中是什么意思?这里的问题不是控制或取消,因为我有有限的窗口来执行所有请求的ping并解析它们的响应,如果我按顺序执行此操作,损失将成倍增加请发布您在 PingThread
。尤其是
PingUtils.executePingRequest(请求)
方法是否尝试同时运行多个异步任务?例如:
task.executeOnExecutor(AsyncTask.THREAD\u POOL\u EXECUTOR)
@Stanojkovic
AsyncTask
线程池执行器
相对于线程或可运行线程进行加权,而默认的
AsyncTask
使用
新的LinkedBlockingQueue(128)
,如果为
AsyncTask
创建自定义池执行器,则不值得。我们在需要主动更新我们的答案时使用
AsyncTask
,请仔细阅读,而不是回答任何堆栈溢出问题question@Acapulco线程创建唯一的对象,而runnable将同一对象共享给多个线程
private class PingThread implements Runnable {
private class PingTask implements Runnable {
class RunnableDemo implements Runnable {
    private Thread thread;
    String threadName="My thread";
    public void run() {
        //do your code from here 'logic'
        System.out.println("Threading is Running");
        try {
            for(int i = 4; i > 0; i--) {
                System.out.println("Thread: "+threadName +" "+ i);
                // Let the thread sleep for a while.
                Thread.sleep(50); //sleep your content for xx miliseconds
            }
        } catch (InterruptedException e) {
            System.out.println("Thread " +  threadName + " interrupted.");
        }
        System.out.println("Thread " +  threadName + " exiting.");
        //finish your work here 
    }

    public void start () {
        System.out.println("Starting " +  threadName );
        if (thread == null) {
            thread = new Thread (this);
            thread.start (); //This will call your run methods of Runnable
        }
    }
}
//test your thread from here
public class TestThread {
    public static void main(String args[]) {
        RunnableDemo R1 = new RunnableDemo( "Thread-1");
        R1.start();

        RunnableDemo R2 = new RunnableDemo( "Thread-2");
        R2.start();
    }   
}