线程上的wait()方法不能正常工作

时间:2015-03-14 08:43:28

标签: java android multithreading wait threadpoolexecutor

我有一些下载作为ThreadPoolExecutor的任务提交。现在,我在扩展Application的全局类中创建此ThreadPoolExecutor。我将所有提交的任务存储在带有ID的HashMap中。

我在ListView中有一个Fragment。此ListView项包含暂停和恢复按钮。当我单击列表项本身时,下载FutureTask将提交给全局池执行程序。现在,当我点击ListView项目的暂停按钮时,我希望该特定线程暂停/等待。

我的列表视图的自定义适配器中有暂停按钮的onClick方法。因此,当我单击按钮时,在我的适配器类中,我获取当前正在运行的所有线程,将它们放入一个数组中,然后从数组中获取具有我想要的名称的线程。我可以在我的日志中看到我想要获取的线程正在以我设置的名称运行。所以一旦我得到那个帖子,我就会wait()

在我的恢复按钮的onclick中,我通知该特定线程并将标志设置为false,以便线程恢复。但是,即使在单击暂停后,该线程内的下载实际上也会继续运行。我不知道我哪里出错了。

我的GlobalState课程:

public class GlobalState extends Application{

HashMap<String, Future<?>> futureMapMain = new HashMap<String, Future<?>>();

    ThreadPoolExecutor mainExec = new ThreadPoolExecutor(2, 2, 2000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new YourThreadFactory());

public void submitTaskMain(String name, Thread task){
        Future<?> longRunningTaskFuture = mainExec.submit(task);
        futureMapMain.put(name, longRunningTaskFuture);
    }

    public HashMap<String, Future<?>> getFutureMap(){
        return futureMapMain;
    }

    public ThreadPoolExecutor getMainExeutor(){
        return mainExec;
    }

public class YourThreadFactory implements ThreadFactory {
           public Thread newThread(Runnable r) {
             return new Thread(r, gettName());
           }
         }
}

我在片段类中编写的下载方法。在列表项上执行点击:

public void abDownloadTask(){

Thread dThread = new Thread(new Runnable() {

                final Handler pdfHandler = new Handler();

                @Override
                public void run() {
                    for(something){
/* DOES SOME DOWNLOAD USING url.getcontent() with different urls in a loop and stores files to sd card. */
}
}
}
dThread.setName(threadname);
            Log.d("Tel Frag", "Thread name set as: "+dThread.getName());
            mainGs.settName(threadname);
            mainGs.submitTaskMain(threadname, dThread);
}

点击自定义列表适配器中的暂停按钮:

    pause.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

                needToPause = true;

                Runnable runnable = new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub

                        Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
                        Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
                        Log.d("CLA", "Threads running size: "+threadArray.length); 

                        Thread neededThread = null;

                         for ( Thread thread : threadArray ){
                             Log.d("CustomListAdapter", "Thread name in array: "+thread.getName());
                                if (thread.getName( ).equals(threadname)){
                                    neededThread = thread;
                                }
                         }   

                         if(neededThread!=null){
                            while(needToPause){
                                synchronized  (neededThread) {
                                        try {
                                            neededThread.wait();
                                        } catch (InterruptedException e) {
                                            // TODO Auto-generated catch block
                                            e.printStackTrace();
                                        }
                                }
                            }
                         } 
                    }
                };
                new Thread(runnable).start();

                notifyDataSetChanged();
        }
    });

onclick我的自定义列表适配器类中的简历按钮:

resume.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            needToPause = false;

            Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
            Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);

             for ( Thread thread : threadArray ){
                    if ( thread.getName( ).equals(threadname) ){
                        thread.notify();
                    }
             }  


            notifyDataSetChanged();
        }
    });

我一直试图弄清楚它2天但没有运气。我经历了很多例子和stackoverflow问题。我只是想通过它的名字获取一个线程,然后暂停并恢复它。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

您无法在wait()个对象上可靠地使用notify()Thread。这在Javadoc中有明确说明。您已经拥有Future个对象,无论如何都不应该使用其他机制。