Thread class for exercises
Chained constructors.
I find it interesting that you described the single-parameter constructor as your &quot;default&quot; one, and the others as &quot;extras&quot;. It's usually the other way around: the constructor that initializes all immutable fields is the &quot;main&quot; one, and any other constructor that works off default values would be &quot;convenience&quot; constructors.

public NumLoopThread(int sleepTime, String threadName, int numberLoops) {
    this.sleepTime = sleepTime;
    this.threadName = threadName;
    this.numLoops = numberLoops;
    thread = new Thread(this, threadName);
    thread.start();
}


Take out numberLoops, you get this one:
public NumLoopThread(int sleepTime, String threadName) {
    // pasta
}

Take out sleepTime, you get this one:
public NumLoopThread(String threadName) {
    // pasta
}

Looks like threadName should be the first parameter in all 3 constructors, for consistency:
public NumLoopThread(String threadName, int sleepTime) {
    // pasta
}


public NumLoopThread(String threadName, int sleepTime, int numberLoops) {
    this.sleepTime = sleepTime;
    this.threadName = threadName;
    this.numLoops = numberLoops;
    thread = new Thread(this, threadName);
    thread.start();
}

That way when you look at your overloads, they all look like they naturally extend each other, in some sort of chain.
You already have your defaults:

private int sleepTime = 400;
private int numLoops = 10;


Consider making them static final, and single-purpose:
private static final int defaultSleepTime = 400;
private static final int defaultNumLoops = 10;

And since the actual fields are only ever assigned in a constructor, they should be marked final, too:
private final int sleepTime;
private final int numLoops;

Use this(); as the first instruction in the body, to &quot;chain&quot; the constructors:
public NumLoopThread(String threadName, int sleepTime) {
    this(threadName, sleepTime, defaultNumLoops);
}

public NumLoopThread(String threadName) {
    this(threadName, defaultSleepTime, defaultNumLoops);
}

Voilà, no more pasta!

That said I'm not sure about start()ing the thread in the constructor; it makes your run method a bit misleading. In general it is not a good idea to pass your 'this' reference to to a thread and start it during construction. The thread could then start with an unfinished object. Generally you should leave the starting of the thread to a separate method. (ref)