There are two ways to create threads

See on the net say what all have, the most authoritative still have to see JDK document, so everybody small partner in this interview question of time do not answer wrong!!

One is to inherit Thread, override the run method, and implement our own logic in the run method

class MyThread extends Thread{

	@override
	public void run(a){
		/* Our own logic */}}new MyThread().start();
Copy the code

In one case, class implements the Runnable interface, overrides the Run method, and creates a new Thread class

class MyTask implements Runnable{

	@override
	public void run(a){
		/* Our own logic */
	}
}

MyTask task = new MyTask;
new MyThread(task).start();
Copy the code

Thread state

It’s all a variable representation at the bottom

private volatile int threadStatus = 0;

– NEW

Threads that have not been started are in this state

– > RUNNABLE

Threads executing in the Java Virtual machine are in this state.

– > BLOCKED

The thread is blocked waiting for the lock to be released, and after entering the synchronized block /synchronized modification method or re-entering the synchronized block /synchronized modification method, Object#wait() is called to enter this state.

The thread in this state is WAITING for another thread to perform a particular operation.

  1. Object#wait() does not specify a timeout
  2. Thread#join() does not specify a timeout
  3. LockSupport#park()

– > TIMED_WAITING

The thread that waits for another thread to perform a specific operation within the specified time is in this state.

  1. Thread#sleep()
  2. Object#wait() specifies the timeout period
  3. Thread#join() specifies the timeout
  4. LockSupport#parkNanos
  5. LockSupport#parkUntil

– TERMINATED

The thread that exits after execution is in this state.

A thread can have only one state at a time, and the state is defined only by the virtual machine, independent of the operating system.

The above can be seen:

  1. After Java calls start(), a thread actually appears in the operating system and runs immediately.

  2. Threads in Java have a one-to-one relationship with threads in the operating system kernel.

  3. After calling start, the thread state becomes RUNNABLE due to some part of the code in the native method.

Name of the thread

If not specified, the default is “thread-n”

public Thread(a) {
    init(null.null."Thread-" +nextThreadNum(), 0);
}
Copy the code

The concept of thread groups (not very common)

Each thread can belong to a thread group. If we do not specify a thread group, the default is to use the thread group of the current executing thread, such as the main thread group.

if (g == null) {
    g = parent.getThreadGroup();
}
Copy the code

Daemon threads

The parent thread is the thread currently executing the creation thread.

If we do not specify whether a thread is a daemon thread, the isDaemon state of the parent thread is used. By default, the parent thread is the daemon thread, as are the child threads, and vice versa.

If a thread is a daemon thread, the daemon thread automatically exits after the main thread exits. If it is a non-daemon thread, it will not exit after the main thread exits, but will exit after all logic has been executed

this.daemon = parent.isDaemon();

Thread ID

Each thread also has the concept of a thread ID, which is used to identify it


/* Set thread ID */
tid = nextThreadID();

private static synchronized long nextThreadID(a) {
    return ++threadSeqNumber;
}
Copy the code

The start method

  1. When we call the start method, the JVM defaults to calling our run method.
  2. A thread’s start method cannot be called more than once, otherwise it will throwIllegalThreadStateExceptionabnormal

Sleep method

  1. Let the current thread sleep, we can specify the number of milliseconds sleep.
  2. Sleep The thread does not lose the lock it owns after it sleeps.
public static native void sleep(long millis) throws InterruptedException;
Copy the code

Since the introduction of the TimeUnit class in JDK1.5, we can easily specify the time to sleep. for example:

TimeUnit.HOURS.sleep(1); / / 1 hour
TimeUnit.MINUTES.sleep(1); / / 1 minutes
TimeUnit.SECONDS.sleep(1);/ / 1 seconds
TimeUnit.MILLISECONDS.sleep(1);/ / 1 millisecond
Copy the code

Yield method

It is usually used for testing and debugging to indicate whether the current thread is willing to abandon the processor it is currently using.

The join method

The main thread creates a child thread and then calls its join method, which blocks the main thread until it completes execution. Of course, depending on the code, we can also specify how many milliseconds to block and how long to wait!

public final synchronized void join(long millis) throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

		// This is the key blocking code, using object.wait ()
    if (millis == 0) {
        while (isAlive()) {
            wait(0); }}else {
				// Millis is the amount of time to wait
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break; } wait(delay); now = System.currentTimeMillis() - base; }}}Copy the code

Interrupted method

case1

There is a flag bit, isInterrupted, that checks if the thread isInterrupted, and if you call interrupt, it returns true, so you can stop performing some action.

The interrupt method is used in conjunction with the isInterrupted flag and does not actually interrupt the thread.

Thread subThread = new Thread(()->{
    try {
        while(! Thread.currentThread().isInterrupted()){ System.out.println("Child thread execution...."); }}catch(InterruptedException e) { e.printStackTrace(); }}); subThread.start(); Thread.sleep(2000);
System.out.println("Interrupt execution of child thread.....");
After interrupted by a child thread, isInterrupted changes to true,
//interrupt
subThread.interrupt();
System.out.println(subThread.isInterrupted());

/* output ------------------ The child thread executes.... The child thread executes.... The child thread executes.... The child thread executes.... Interrupt execution of the child thread..... true // java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.mazai.concurrent.Demo2.lambda$main$0(Demo2.java:13) at  java.lang.Thread.run(Thread.java:748) */
Copy the code

case2

It is also possible to interrupt a thread to wake up from sleep.

public static void main(String[] args) {
    MyThread myThread = new MyThread();
    myThread.start();
    myThread.interrupt();
}

private static class MyThread extends Thread{
    private boolean isRun = true;
    @Override
    public void run(a){
        while (isRun){
            try {
                System.out.println("Sleep 5 s...");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                isRun = false; }}}}/* output ----------------------- sleep 5s...... java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.mazai.concurrent.Demo2$MyThread.run(Demo2.java:21) */
Copy the code