Skip to content

Sequences and multithreading

jld73 edited this page Jun 5, 2017 · 3 revisions

The sequence class

Fields

sequenceLock

The sequenceLock is a java Object. This is used to control the execution of the threads by calling wait() to suspend execution, and notify() to wake this thread back up.

terminated

A boolean that tracks whether the sequence has finished its execution. This is checked in the scratch Act method, and any sequence with terminated = true will be removed from the list.

triggered

A boolean used to track whether the conditions are met that this sequence should activate. For example, if the corresponding key to a keyPressedSeq has been pressed.

isReady

A boolean that tracks whether this sequence has been started. When scratch begins the sequence it is set to true, allowing it to leave its suspended state.

objToCall

The object in which the script the sequence will call resides

methodToCall

The name of the method this sequence should call

Methods

There are also several methods in the sequence class

run

Run is the method that will be run by a separate thread when the start method is called. The first part is a loop that causes the thread to wake up every 100ms and check if it's been interrupted. If it has, it will exit. Otherwise, if it is ready to begin, it will leave the loop. This will only happen once the performSequence method has been called. The next part gets the appropriate method and begins invoking it. If the invoked method terminates normally without any yield calls, the script will become terminated, and the thread will end. If there are loops in the invoked method, execution will remain stuck in invoked method until it either returns or is otherwise interrupted.

waitForNextSequence

This is called when the sequence yields. This causes the thread to call notify, which wakes up the main thread again, allowing it to to continue with the next sequence. After waking the main thread up, this thread will call wait, suspending execution until the main thread calls performSequence again. This should not happen until the next call to act.

performSequence

This is called by the main thread on each sequence once per frame. It first sets isReady to true, allowing the thread to begin execution, if it hasn't already. Next it notifies the sequenceLock, causing it to start executing if it was suspended. Now that the other thread is running, the main thread will call wait, suspending execution until the other thread has finished its execution, or has reached a call to yield. Once the happens, the main thread will continue to activate the next sequence.

Life of a thread

  • In the sprite's constructor the method WhenFlagClicked is called.
  • A new sequence is created and added to the list of sequences
    • The newly created sequence is started, creating a new thread
    • The new thread is now stuck in a loop of waiting for isReady to become true
  • The start button in greenfoot has now been pressed, and act is called.
  • Act iterates through the list of sequences, finding our sequence
  • performSequence is called, the main thread sets doneSequence to false
  • The main thread calls notify waking up the other thread
  • The main thread calls wait, suspending its execution while the sequence runs
    • The sequence begins executing the WhenFlagClickedCb0 method
    • The sequence calls yield
    • The sequence calls waitForOtherSequence which sets doneSequence to true
    • The sequence calls notify, waking the main thread up
    • The sequence calls wait, suspending execution.
  • The main thread now continues on to any other sequences
  • Next frame, act is called again, restarting the process