[SPARK-4097] Fix the race condition of 'thread'

There is a chance that `thread` is null when calling `thread.interrupt()`.

```Scala
  override def cancel(): Unit = this.synchronized {
    _cancelled = true
    if (thread != null) {
      thread.interrupt()
    }
  }
```
Should put `thread = null` into a `synchronized` block to fix the race condition.
Here is the codes of `cancel`:
```Scala
1 override def cancel(): Unit = this.synchronized {
2    _cancelled = true
3    if (thread != null) {
4      thread.interrupt()
5    }
6  }
```
Without `ComplexFutureAction.this.synchronized`, the codes can run in the following order:

1. In thread T1, `cancel` is called.
2. After T1 finishes L3, it's suspended.
3. Assume T2 is the thread that runs the action. Now T2 is set `thread` to null.
4. T1 is resumed and runs L4 (thread.interrupt()), because `thread` is null, it will throw a NPE.