一个线程如何去控制另一个线程

J2EE 码拜 9年前 (2015-04-21) 1369次浏览 0个评论

有一个线程已经启动,并且是顺序执行代码,代码也就只会执行一次,现在我想在外部发送一个请求,暂停那个已经开始执行的线程,或者取消已经运行的线程,如何做啊?各位大神,帮帮忙啊,用的语言是JAVA,希望不是简单的说什么用wait和notify,我用了wait,抛出illegalmonitorstateexception异常,就算我用suspend都挂起不了,有谁做过这样的例子吗。这种方式是基于web形式的

一个线程如何去控制另一个线程
你可以设置一个全局变量 起初为true  每次知心线程时判断变量是否为true   你外部更改这个变量值 就可以控制线程
一个线程如何去控制另一个线程
引用 1 楼 u010533788 的回复:

你可以设置一个全局变量 起初为true  每次知心线程时判断变量是否为true   你外部更改这个变量值 就可以控制线程了

感谢你的回答,这个方法我肯定是想到的,只是说这个线程只会执行一次,如果执行完代码就不存在了,并且是在执行过程中控制线程,不是一开始就可以检测这个变量的,并且执行的代码也不是循环执行的

一个线程如何去控制另一个线程
用PipedOutputStream和PipedInputStream ,给那个线程发给信号,让它自己暂停或者取消!
一个线程如何去控制另一个线程
引用 3 楼 longtian1213 的回复:

用PipedOutputStream和PipedInputStream ,给那个线程发给信号,让它自己暂停或者取消!

没用过啊,有简单例子可以借鉴吗

一个线程如何去控制另一个线程
PipedInputStream类 和 PipedOutputStream类 的简单介绍和代码演示
一个线程如何去控制另一个线程
有谁有好的方法吗?????
一个线程如何去控制另一个线程
像你这种场景完全可以通过线程实例调用wait()方法去停止
一个线程如何去控制另一个线程
可以写成一个观察者模式 ,通过观察者去调用具体线程实例的wait()
一个线程如何去控制另一个线程
LockSupport 很简单的例子

import java.io.IOException;
import java.util.concurrent.locks.LockSupport;

public class ThreadSuspend {

    /**
     * 
     * @param args
     * @throws IOException
     * @throws InterruptedException
     */
    public static void main(String[] args) throws IOException,
            InterruptedException {
        ThreadExt threadExt = new ThreadExt();

        Thread.sleep(7000); // let thread work about 7 sec

        System.out.println("Ready to suspend the Thread "
                + threadExt.toString());
        threadExt.suspendWorkflow(); // suspend the thread

        Thread.sleep(5000);
        System.out
                .println("Ready to resume the Thread " + threadExt.toString());
        threadExt.resumeWorkFlow(); // at last, resume the thread.
    }

    static class ThreadExt extends Thread {
        private volatile boolean isPark = false;
        private volatile boolean isWorkingAgain = false;

        public ThreadExt() {
            this.setName("Thread-ext");
            this.start();
        }

        public void suspendWorkflow() {
            this.interrupt();
            this.isPark = true;
        }

        public void resumeWorkFlow() {
            LockSupport.unpark(this);
            this.isPark = false;
            this.isWorkingAgain = true;
        }

        @Override
        public void run() {

            final Thread cThread = Thread.currentThread();
            while (!cThread.isInterrupted()) {
                try {
                    while (isPark) {
                        LockSupport.park();
                    }
                    work();
                    System.out
                            .println(isWorkingAgain ? "yeh, i am working again.."
                                    : "yeh, i am working..");
                } catch (InterruptedException e) {
                    System.out.println("oh no, i was been Interrupted..");
                    continue;
                }
            }
        }

        private void work() throws InterruptedException {
            Thread.sleep(1000);
        }
    }

}

一个线程如何去控制另一个线程
引用 7 楼 u010557116 的回复:

像你这种场景完全可以通过线程实例调用wait()方法去停止

我是获取到了那个线程的实例,并且调用了wait方法,可是貌似wait方法只能挂起它被调用的方法所在的线程,不能让需要暂停的线程挂起,例如aa.wait(),aa是需要暂停的线程,可是aa线程并没有被挂起

一个线程如何去控制另一个线程
引用 9 楼 shnulaa 的回复:

LockSupport 很简单的例子

import java.io.IOException;
import java.util.concurrent.locks.LockSupport;

public class ThreadSuspend {

    /**
     * 
     * @param args
     * @throws IOException
     * @throws InterruptedException
     */
    public static void main(String[] args) throws IOException,
            InterruptedException {
        ThreadExt threadExt = new ThreadExt();

        Thread.sleep(7000); // let thread work about 7 sec

        System.out.println("Ready to suspend the Thread "
                + threadExt.toString());
        threadExt.suspendWorkflow(); // suspend the thread

        Thread.sleep(5000);
        System.out
                .println("Ready to resume the Thread " + threadExt.toString());
        threadExt.resumeWorkFlow(); // at last, resume the thread.
    }

    static class ThreadExt extends Thread {
        private volatile boolean isPark = false;
        private volatile boolean isWorkingAgain = false;

        public ThreadExt() {
            this.setName("Thread-ext");
            this.start();
        }

        public void suspendWorkflow() {
            this.interrupt();
            this.isPark = true;
        }

        public void resumeWorkFlow() {
            LockSupport.unpark(this);
            this.isPark = false;
            this.isWorkingAgain = true;
        }

        @Override
        public void run() {

            final Thread cThread = Thread.currentThread();
            while (!cThread.isInterrupted()) {
                try {
                    while (isPark) {
                        LockSupport.park();
                    }
                    work();
                    System.out
                            .println(isWorkingAgain ? "yeh, i am working again.."
                                    : "yeh, i am working..");
                } catch (InterruptedException e) {
                    System.out.println("oh no, i was been Interrupted..");
                    continue;
                }
            }
        }

        private void work() throws InterruptedException {
            Thread.sleep(1000);
        }
    }

}

因为线程里面的代码只会执行一次,所有不能使用循环,就不能够进行判断标志位,这怎么解决?

一个线程如何去控制另一个线程
thread run里面的方法做代理 AOP , 前置 后置处理 加上

while (isPark) {
                        LockSupport.park();
                    }

操作

一个线程如何去控制另一个线程
5分
你可以通过一个观察者去管理一个Map ,这个map保存的是一个线程id和线程实例 ,你可以从Map拿到实例调用  interrupt方法进行中断
一个线程如何去控制另一个线程
或者可以把线程交给线程池管理 然后调用shutdown 方法
一个线程如何去控制另一个线程
mark下,自己也试了下,要是直接终止的话好办,要是暂停的话还没实现
一个线程如何去控制另一个线程
引用 15 楼 nyxiaobin123 的回复:

mark下,自己也试了下,要是直接终止的话好办,要是暂停的话还没实现

终止你是如何做到的?请说说

一个线程如何去控制另一个线程
引用 14 楼 u010557116 的回复:

或者可以把线程交给线程池管理 然后调用shutdown 方法

我用executor来开始的线程,不知道能不能用到,明天试试

一个线程如何去控制另一个线程
引用 16 楼 h04072019 的回复:
Quote: 引用 15 楼 nyxiaobin123 的回复:

mark下,自己也试了下,要是直接终止的话好办,要是暂停的话还没实现

终止你是如何做到的?请说说

拿到线程直接interrupt(),但是直接sleep或者wait之类是不起作用的,楼上说的管道啊、观察者模式都无法判断在哪操作,你说的,线程就顺序执行一遍,又不能循环,总不能执行一句业务代码判断一次吧,我理解的没错吧

一个线程如何去控制另一个线程
引用 18 楼 nyxiaobin123 的回复:
Quote: 引用 16 楼 h04072019 的回复:
Quote: 引用 15 楼 nyxiaobin123 的回复:

mark下,自己也试了下,要是直接终止的话好办,要是暂停的话还没实现

终止你是如何做到的?请说说

拿到线程直接interrupt(),但是直接sleep或者wait之类是不起作用的,楼上说的管道啊、观察者模式都无法判断在哪操作,你说的,线程就顺序执行一遍,又不能循环,总不能执行一句业务代码判断一次吧,我理解的没错吧

是的,你理解的很对,其实线程里面执行的是许多句sql语句,所以只是执行一遍。我之前试了interrupt,不知道为什么也没起作用。你暂停有什么思路吗?

一个线程如何去控制另一个线程
5分
引用 19 楼 h04072019 的回复:
Quote: 引用 18 楼 nyxiaobin123 的回复:
Quote: 引用 16 楼 h04072019 的回复:
Quote: 引用 15 楼 nyxiaobin123 的回复:

mark下,自己也试了下,要是直接终止的话好办,要是暂停的话还没实现

终止你是如何做到的?请说说

拿到线程直接interrupt(),但是直接sleep或者wait之类是不起作用的,楼上说的管道啊、观察者模式都无法判断在哪操作,你说的,线程就顺序执行一遍,又不能循环,总不能执行一句业务代码判断一次吧,我理解的没错吧

是的,你理解的很对,其实线程里面执行的是许多句sql语句,所以只是执行一遍。我之前试了interrupt,不知道为什么也没起作用。你暂停有什么思路吗?

大概的想法是在执行的线程里再开个监听啥的,不过现在没有细想,要去搬我自己的砖啊

一个线程如何去控制另一个线程
5分
我后来思考了下 ,其实你这个问题就是一个矛与盾,线程本来就是一个独立的。而你这种情况是属于强行破坏,目前Java 层面只提供了stop方法,这个方法是有风险,这个你可以具体看api说明,如果你这个线程不存在占用公共资源系统资源等的话,你可以通过线程实例直接stop,但是如果的线程里有占用公共资源等的话,你则需要先释放掉在stop ,这里则会出现当你正在使用资源时?你怎么释放?比如一个stream ?你能释放掉吗?      所以说这就是一个矛与盾问题。看你怎么把握
一个线程如何去控制另一个线程
10分
如果是 想要 尽快的结束线程。需要在逻辑上文章。

而不是在thread 的实例上做文章 比如说thread.stop

首先需要考虑到 程序中那些内容可能会阻塞到该线程的运行,
一般有

socket.accept();     // socket.close 可以打断 throw ioException
procedure.execute();   // close connection 可以打断 throw sqlException
Object.wait();    // Object notify 可以打断 
inputStream.read();  // close inputstream可以打断   throw ioException

所以说想结束一个线程。是需要在代码逻辑中进行处理的。比如先说以上的资源需要先处理关闭。继而线程的的生命周期也就随之停止了。

还有需要注意的是 资源的释放问题。

一个线程如何去控制另一个线程
10分
被“控制”的线程绝对不可能什么都不改就被你控制了,
如果说就按你的条件,顺序执行,中间又不进行任何检测,那么基本上你没办法控制它
一个线程如何去控制另一个线程
好有深度的问题,不懂了
一个线程如何去控制另一个线程
5分
去看看java。util。concuurent包,executorService方法可能能满足你的需求。
例子连接
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html
其中
Method submit extends base method Executor.execute(java.lang.Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion. Methods invokeAny and invokeAll perform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete. (Class ExecutorCompletionService can be used to write customized variants of these methods.)
一个线程如何去控制另一个线程
结贴了,做个总结。感谢大家的回答,23楼说的很对,想要控制一个线程,中间肯定有相关检测,后来我发现确实我的线程中调用的方法确实有一个循环可以使用进行判断检测,如果只是一个顺序执行,那么就不会存在控制问题,极端情况下就是一下子执行完,不会让你控制了。所以实际需求中可能不太会出现。还有基本控制方法就是检测标志位和使用wait和notify进行暂停和恢复控制,取消线程在执行阶段可以使用判断标志位的方式,在wait时使用中断interrupt方式。可以使用线程直接中断,或者使用executorService方法返回的future里面的cancle方法。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明一个线程如何去控制另一个线程
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!