Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
Multithreading 处理线程之间的状态更改_Multithreading_Oop_Design Patterns_Concurrency - Fatal编程技术网

Multithreading 处理线程之间的状态更改

Multithreading 处理线程之间的状态更改,multithreading,oop,design-patterns,concurrency,Multithreading,Oop,Design Patterns,Concurrency,我有一个工作线程,它需要根据另一个线程(比如与用户交互的线程)给出的命令执行各种任务。工作线程需要执行以下功能 a。一旦启动,工作线程需要等待用户线程给出任务。 B一旦给定了任务,工作线程需要继续执行该任务,除非要求执行其他任务。 C在任何时间点,用户线程都可以要求工作线程停止(退出)、暂停、继续、暂停并等待另一个任务等 在处理多线程程序时,我多次遇到这个用例,结果常常使用复杂的逻辑(很多if/else、信号量signal/wait等) 所以我想知道这个用例是否有好的设计模式 object th

我有一个工作线程,它需要根据另一个线程(比如与用户交互的线程)给出的命令执行各种任务。工作线程需要执行以下功能

a。一旦启动,工作线程需要等待用户线程给出任务。
B一旦给定了任务,工作线程需要继续执行该任务,除非要求执行其他任务。
C在任何时间点,用户线程都可以要求工作线程停止(退出)、暂停、继续、暂停并等待另一个任务等

在处理多线程程序时,我多次遇到这个用例,结果常常使用复杂的逻辑(很多if/else、信号量signal/wait等)

所以我想知道这个用例是否有好的设计模式

object thisLock;
bool paused;
bool exit;

void YourThread() {

    while (true)
    {

        lock (thisLock)
        {

            if (exit) return;

            while (paused)
                Monitor.Wait(thisLock);


        }

        //do some work
        //process one item
        //whatever

    }

}
停顿-

paused = true;
解除-

lock (thisLock)
{
    paused = false;
    Monitor.Pulse(thisLock);
}
退出

exit = true;
在这些情况下,该选项可能非常适合。我正在研究,您可以阅读更多关于在中使用角色构建软件的内容。为了给你一些关于你所描述的工作者实体的印象,考虑下面的代码(在Scala中编写,但应该是自己描述的):

特征状态
案例对象空闲扩展状态//无工作状态的标记对象
案例对象活动扩展状态//标记对象,用于有工作要做时
案例对象暂停扩展工作已知但暂停时的状态//标记
类Worker extends Actor extends FSM[State,Option[Work]]{
startWith(空闲,无)//开始时没有工作要做
何时(空闲){
案例事件(DoWork(工作包))=>
self!KickMe//发送给此演员的消息,以使其执行某些工作
使用某些(工作包)转到(活动)
}
何时(激活){
案例事件(KickMe,一些(工作))=>
执行(工作)
赛尔夫!踢我//这会让工作继续进行,除非另有说明
停留()
案例事件(暂停,))=>
转到(暂停)
}
何时(暂停){
//在此状态下,KickMe消息将被忽略,导致暂停
案例事件(恢复,41;=>
赛尔夫!踢我
转到(活动)
}
未处理时{//这些情况适用于所有三个州
案例事件(停止)=>
停止()
案例事件(DropIt,41;=>
使用None//将当前工作包归零,转到(空闲)
}
def execute(work:work)=……//无论要做什么
}
然后,您可以通过向其发送消息与此进行交互:

//初始化Akka
val系统=ActorSystem(“演示”)
//实例化actor,返回ActorRef
val workerRef=system.actorOf(Props[Worker],name=“Fred”)
//发送第一个工作包以使其运行
workerRef!DoWork(new MyWork(…)//无论工作包是什么
... // 过了一段时间
workerRef!暂停
... // 然后甚至以后可能
workerRef!简历
... // 最后
workerRef!停止

上面的实现不是100%防弹的(因为我想重点演示一般原理),它也不是在Akka中编写类似内容的唯一方法。重要的一点是,您不需要显式地管理线程,只需要管理参与者,Akka会注意在线程上运行它们,并在它们之间安全地传递消息。如果这看起来很有趣,请随时查询有关的更多信息。

您的逻辑很可能会变得复杂,因为您试图让单个实体做太多的工作(这会导致O(N!)复杂性)


如果您将线程安全作为策略(线程安全/不安全队列、同步点、标志等)以及其他行为方面,那么worker和策略都将是简洁设计的紧凑可重用Lego块。

这里我发布了一个方法的标题-它帮助我作为while循环的先决条件:

private static final boolean conditionMet (
    final boolean isEventDispatchThread    
    , final List<AWTEvent> pendingEvents
    , final AtomicBoolean isDefaultEventQueue
    , final AtomicBoolean isEventQueueChanging
    , final AtomicReference<DispatchableEventQueue> newEventQueue
    , final AtomicReference<ProgressMonitor> processMessageBlocking
    , final AtomicInteger actionsRemaining
    , final AtomicBoolean interruptAction
    , final AtomicReference<Tuple2<IAction, Throwable>> throwableWasThrownFromChain        
    , final ConcurrentHashMap<IAction, Boolean> valuesReadyToBeSetFromEDT
    , final ConcurrentHashMap<IAction, Boolean> valuesWasSetFromEDT
    , final ConcurrentHashMap<IAction, Boolean> onSwingReadyToBeRunFromEDT
    , final ConcurrentHashMap<IAction, Boolean> onSwingWasActuallyRunFromEDT
    , final FlexReference<Map<String, Object>> remoteRef        
) throws InterruptedException {
private静态最终布尔条件满足(
最终布尔值isEventDispatchThread
,最终列表待定事件
,最终原子布尔isDefaultEventQueue
,最终原子布尔值为eventqueuechanging
,最终原子引用newEventQueue
,最终原子引用进程MessageBlocking
,最终原子整数操作保留
,最终原子布尔中断动作
,最终原子参考废物从链中排出
,最终ConcurrentHashMap值从EDT重新设置
,最终ConcurrentHashMap值SwassetFromedt
,最终ConcurrentHashMap onSwingReadyToBeRunFromEDT
,WingWas上的最终ConcurrentHashMap实际为YrunFromedt
,最终FlexReference remoteRef
)抛出中断异常{

我可能仍然想知道这是否是一个好的设计模式,但是通过使用状态机或不使用状态机,如果您试图在一个地方(同时)使事情更简单,那么在另一个地方(条件)得到更大的混乱就不难了对我来说,中间的方法是在更高的层次上进行编程,并将所有这些超时视为理所当然,而不是可用性和死亡。

这确实是一个非常不寻常的情况,一点也不典型。一般来说,如果有工作需要做,你就去做。必须停止、暂停、继续或等待是非常不寻常的。我为你编写了多线程程序十多年过去了,从来没有做过这些事情(除了在毫无事可做的情况下等待工作,但这是基本工作调度机制的一部分,不是额外的事情)@DavidSchwartz:我在应用程序级别处理这些用例,用户请求可以以任何顺序出现。一个很好的例子是摄像头应用程序:启动应用程序、启动预览、暂停预览、拍照、锁定屏幕、退出应用程序等。所有这些用例都涉及停止特定工作的完成,而不是停止线程。当你想暂停预处理视图中,您不关心哪个线程正在执行此操作,甚至不关心某个线程是否在该特定时间执行此操作。您要暂停的是工作的预览--该过程中涉及的是一个线程还是五十个线程。