首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使线程从主线程等待

使线程从主线程等待
EN

Stack Overflow用户
提问于 2018-08-10 13:50:48
回答 2查看 126关注 0票数 1

我读过很多关于让线程等待的消息,但是我不能让任何东西工作。我读过关于等待、通知、加入的文档,lock...but仍然找不到解决我问题的方法。

我有我的主流和另一个流的背景(用户不与它互动,它只是自己的东西)。在主流,用户将有可能使用某些功能,直到他退出程序。我想要的是,当用户选择使用一个函数时,后台的流在此函数期间暂停,然后再启动。

我将在这里用“伪”代码解释它:

代码语言:javascript
复制
main(args[]){
    new Thread(new Background(), "Background").start();
    while (user don't quit){
        //user choose a function
        -> find a way to pause Background thread
        chosenFunction();
        -> find a way to unpause the Background thread
    }
}

public class Background implements Runnable{
    public Background(){}
    public void run(){
        while (thread is not paused){
            //do some stuff
        }
    }
}

我不认为我应该使用join,因为我不想等待另一个线程的完成,而是等待在另一个线程中函数的完成。我原以为锁是答案,但我无法使它起作用。我试过了:

代码语言:javascript
复制
main(args[]){
    ReentrantLock lock = new ReentrantLock();
    new Thread(new Background(lock), "Background").start();
    while (user don't quit){
        //user choose a function
        lock.lock();
        chosenFunction();
        lock.unlock();
    }
}

public class Background implements Runnable{
    private final ReentrantLock lock;
    public Background(ReentrantLock lock){
        this.lock = lock;
    }
    public void run(){
        while (!lock.islocked()){
            //do some stuff
        }
    }
}

或与:

代码语言:javascript
复制
public void run(){
    while(lock.isLocked){
        sychronized(this){
            wait();
        }
    }
//do some stuff
}

但这行不通。

如果您需要更多的上下文:后台的线程正在等待来自套接字的消息,并且用户可以调用的函数也在使用这个套接字。所以是的,我的第一个想法是把这个套接字作为两个流之间的同步对象,但是我也没能让它工作。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-10 14:33:56

您可以使用volatile变量。这是volatile变量的一个非常典型的用例。

代码语言:javascript
复制
public void main() {

    BackgroundServiceThread bst = new BackgroundServiceThread();
    bst.start();

    while (true) {
        //user choose a function
        bst.isPaused = true;
        chosenFunction();
        bst.isPaused = false;
    }
}

private static class BackgroundServiceThread extends Thread {

    volatile boolean isPaused = false;

    @Override
    public void run() {
        while (true) {
            if (!isPaused) {
                //do stuffs;
            }
        }
    }
}

private void chosenFunction() {
    //user choose function
}

在主线程中更新isPaused时,这些更改在后台服务线程中立即可见,因为它是易失性的。

票数 1
EN

Stack Overflow用户

发布于 2018-08-10 14:00:53

在第一个示例中:

代码语言:javascript
复制
new Thread(new Background(), "Background").start();
while (user don't quit){
    //user choose a function
    -> find a way to pause Background thread
    chosenFunction();
    -> find a way to unpause the Background thread
}

第一个问题是:为了让了解其他对象的,您需要某种句柄。而你在这里却没有。

意思:您的代码创建一个新的线程,并启动它。但是,对该线程的引用将被丢弃。除非保留对它们的引用,否则无法标识对象。Background对象也是如此。

换句话说:当您希望多个线程相互通信时,您需要在双方之间建立一个通信通道。例如:两个线程实现都可以访问的对象。

比如(这里的伪代码):

代码语言:javascript
复制
 Queue<String> commands = ...

 new EnhancedThread(commands).start();

上面的内容将启动一个新线程,该线程可以在commands队列上“侦听”命令。这样,您的主线程就可以完成:

代码语言:javascript
复制
 commands.add("COMMAND1");
 commands.add("SUSPEND");

诸若此类。

重复:仅仅创建一个线程对象什么也不做。你必须考虑一种可以用来完成任务的协议。因此:这里关注的是设计方面。把你的线想象成人类。现在扪心自问,要让这些人有这样的互动,你需要具体做些什么。

您当前的实现可以归结为“在街上与一个随机的人交谈,然后离开他。”但在你离开后,随机的人会对你有什么反应呢?你没有问他的电话号码,你打算怎么给他发消息?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51788032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档