Android:方法

时间:2015-08-10 22:19:31

标签: java android

在Android Studio中,我有一个包含在类似方法中的线程(如下所示),因为我想在调用时重新启动线程 [1],(重新创建线程而不是重新启动)

public void callthread(){

   final Thread myThread = new Thread(new Runnable()
   {
       @Override
       public void run()
       {
           for (int x=0; x<750&&!Thread.interrupted(); x++) {
               //using this and thread sleep for repeated timed code within a thread

               try {
                   Thread.sleep(4);
                   runOnUiThread(new Runnable()
                   {
                       @Override
                       public void run() {

                           //some code

                           if (condition) {      
                               myThread.interrupt();
                           }
                       }
                   });

               } catch (InterruptedException e) {

               }
           }
       }
   });

我的问题是它不允许我在我的代码中的所需位置使用myThread.interrupt();,给我一个错误,说“变量'myThread'可能尚未初始化”并且因此不会编译。但是,当整个线程包含在类中但它没有办法重新启动时,它可以工作。换句话说,我需要一种在线程包含在方法中时中断线程的方法。 [2]

接受的解决方案

[1]。 可以重新启动线程的解决方案

[2]。 线程可以在线程包含在方法中时被中断的解决方案

PS:如果不清楚,我已经编辑了上面的代码以便于阅读,但我没有删除像for循环或Thread.sleep这样的内容,因为我认为它们可能是问题的一部分。因此,如果某个大括号中的太多或太少,那么这不是问题

编辑:搜索一下,显然你不能重新开始一个线程

5 个答案:

答案 0 :(得分:2)

在进入for循环之前,您可以在myThread中启动中断线程。中断线程休眠5秒,然后中断myThread。中断在异常处理程序中处理。循环变量x重置为0,这实际上是循环的重启。

public class ThreadInterruptRestart {

    public static void main(String[] args) {
        new ThreadInterruptRestart().callthread();
    }

    public void callthread() {

        final Thread myThread = new Thread("myThread") {
            @Override
            public void run() {
                final Thread _this = this;

                Thread interruptingThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            // this is not the interrupt we are interested in
                            e.printStackTrace();
                        }
                        if (true) {
                            System.out.println("interrupting " + _this + " from thread " + this);
                            _this.interrupt();
                        }
                    }
                }, "interrupting thread");
                interruptingThread.start();

                for (int x = 0; x < 750; x++) {
                    // using this and thread sleep for repeated timed code
                    // within a thread
                    try {
                        System.out.println(x);
                        Thread.sleep(10);
                    } catch (InterruptedException e1) {
                        // this is the interrupt we want to handle
                        System.out.println("" + this + " interrupted!");
                        // reset the loop counter
                        x = 0;
                    }
                }
            }
        };
        myThread.start();
    }
}

另一个myThread没有睡眠的版本,而是使用同步代替InterruptedException

public class ThreadInterruptRestart {

    public static void main(String[] args) {
        new ThreadInterruptRestart().callthread();
    }

    public void callthread() {

        final Object mutex = new Object();

        final Thread myThread = new Thread("myThread") {
            @Override
            public void run() {
                final Thread _this = this;

                Thread interruptingThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            // this is not the interrupt we are interested in
                            e.printStackTrace();
                        }
                        if (true) {
                            System.out.println("interrupting " + _this + " from thread " + this);
                            synchronized (mutex) {
                                _this.interrupt();
                            }
                        }
                    }
                }, "interrupting thread");
                interruptingThread.start();

                for (int x = 0; x < 75000; x++) {
                    // using this and thread sleep for repeated timed code
                    // within a thread
                    synchronized (mutex) {
                        System.out.println(x);
                        // do other stuff here
                    }
                    if (Thread.interrupted()) {
                        // this is the interrupt we want to handle
                        System.out.println("" + this + " interrupted!");
                        // reset the loop counter
                        x = 0;
                    }
                }
            }
        };
        myThread.start();
    }
}

答案 1 :(得分:1)

有更好的方法来结束线程。但是,如果您必须访问该线程,请使用如下的引用变量:

 public void callthread(){

   final Thread myThread = new Thread(new Runnable()
   {
       @Override
       public void run()
       {
           final Thread _this = this;
           for (int x=0; x<750&&!Thread.interrupted(); x++) {
               //using this and thread sleep for repeated timed code within a thread

               try {
                   Thread.sleep(4);
                   runOnUiThread(new Runnable()
                   {
                       @Override
                       public void run() {

                           //some code

                           if (condition) {      
                               _this.interrupt();
                           }
                       }
                   });

               } catch (InterruptedException e) {

               }
           }
       }
   });

答案 2 :(得分:1)

代码中的缺陷是&#34;泄漏此构造函数&#34;在线程实例化之前,您尝试调用对象的(在您的情况下)线程的方法。

要解决此问题,您可以选择类似于观察者模式的设计

答案 3 :(得分:1)

这有用吗?

作为旁注,runOnUiThread是一种代码味道,可能导致一些相当微妙的时间错误。你用它做什么用的?要告诉你在这里想要达到的目标也很难。使用类似执行程序的东西可能会大大简化事情。

public void callthread()
{

    final Thread myThread = new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            final Thread thread = Thread.currentThread();
            for (int x = 0; x < 750 && !Thread.interrupted(); x++)
            {
                //using this and thread sleep for repeated timed code within a thread

                try
                {
                    Thread.sleep(4);
                    runOnUiThread(new Runnable()
                    {
                        @Override
                        public void run()
                        {

                            //some code

                            if (true)
                            {
                                thread.interrupt();
                            }
                        }
                    });

                }
                catch (InterruptedException e)
                {

                }
            }
        }
    });
}

答案 4 :(得分:0)

部分问题是您在嵌套任务类中迷失了方向。另一部分是您尝试使用线程机制来进行逻辑控制。因此,让您的课程控制自己,并保持您的线程模型简单。

<强> ParallelTask

/**
 * An implementation of your inner Runnable.
 */
public class ParallelTask implements Runnable
{
    protected ParallelTaskRunner m_runner = null ;

    private ParallelTask() {} // Disallow default constructor.

    public ParallelTask( ParallelTaskRunner runner )
    { m_runner = runner ; }

    @Override
    public void run()
    {
        // The code from that original inner class.
        if( /* trigger condition */ )
            m_runner.stop(this) ;
    }
}

<强> ParallelTaskRunner

/**
 * An implementation of the outer class.
 */
public class ParallelTaskRunner implements Runnable
{
    public static final int THREAD_COUNT = 750 ;

    protected boolean m_bRunning = false ;
    protected ParallelTask m_tskStopper = null ;

    @Override
    public void run()
    {
        if( m_bRunning ) return ; // Don't run if already running.
        m_bRunning = true ; m_tskStopper = null ;
        for( int i = 0 ; i < THREAD_COUNT && m_bRunning ; i++ )
        {
            try
            {
                // Insert some wait interval here if desired.
                (new Thread( new ParallelTask(this) )).run() ;
            }
            catch( Exception x )
            {
                Log.w( "ParallelTaskRunner.run()",
                       "Caught exception.", x ) ;
            }
        }
    }

    public synchronized void stop( ParallelTask tsk )
    {
        m_bRunning = false ;
        if( m_tskStopper == null )
            m_tskStopper = tsk ;
    }

    public ParallelTask getStopper()
    { return m_tskStopper ; }
}
然后,在某些消费者阶层......
public void callThreads()
{
    ParallelTaskRunner runner = new ParallelTaskRunner() ;
    (new Thread(runner)).run() ;
}

callThread()方法中,您可以根据runner中包含的数据显示报告。例如,如果您的线程使用UUID或简单整数(循环的索引?)唯一标识自己,那么您的应用程序可以使用&#34; stop&#34;来显示toast。任务的ID。如果您在ParallelTask中执行的代码会写出有趣的数据,那么这些数据可以通过ParallelTask中的访问者提供,然后您可以通过首先调用{{1}来调用然后对该runner.getStopper()实例进行操作。