Fast recognize thread

 Reference herein from high concurrency Java programming explain

 

1, create and start a thread

Here is the program code does not add threads.

package concurrent.chapter01;

import java.util.concurrent.TimeUnit;
public class TryConcurrency {
    public static void main(String[] args) {
        browseNews();
        enjoyMusic();
    }
    private static void browseNews() {
        while(true) {
            System.out.println("Uh-huh,the good news.");
            sleep(1);
        }
    }
    private static void enjoyMusic() {
        while(true) {
            System.out.println("Uh-huh,the nice music");
            sleep(1);
        }
    }
    private static void sleep(int i) {
        try {
            TimeUnit.SECONDS.sleep(i);
        }catch (Exception e) {
            
        }
    }
}

Results are as follows:

The program will never execute the second method. So we need to use threads.

Created here by way of anonymous inner class thread, and rewrite the run of these methods, make the program run interactively.

package concurrent.chapter01;

import java.util.concurrent.TimeUnit;
public class TryConcurrency {
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                enjoyMusic();
            }
        }.start();
        browseNews();
    }
    private static void browseNews() {
        while(true) {
            System.out.println("Uh-huh,the good news.");
            sleep(1);
        }
    }
    private static void enjoyMusic() {
        while(true) {
            System.out.println("Uh-huh,the nice music");
            sleep(1);
        }
    }
    private static void sleep(int i) {
        try {
            TimeUnit.SECONDS.sleep(i);
        }catch (Exception e) {
            
        }
    }
}

Results are as follows:

note:

1, create a thread, we need to override the run method of Thread, Override annotation is to rewrite the identity, then enjoyMusic to his execution.

2, start a new thread needs to start rewriting Thread method, only representatives derive a new thread, or Thread and other common no different Java objects, start to put law is a method returns immediately, does not make the program into obstruction.

If you are using Lambda expressions transformation of the above code, the code will become more concise.

public static void main(String[] args) {
        new Thread(TryConcurrency::enjoyMusic).start();
        browseNews();
    }

2, thread creation and the end of the life cycle.

1, the new thread state.

When we create a Thread object with the keyword new, this time he is not being executed, because useless start to start the thread, then the state of the thread is NEW state, to be exact, it's just the state of the Thread object, because in before useless start, the thread does not exist, no difference with you to create a normal Java object with the new.

2, RUNNABLE state of the thread

RUNNABLE thread object into the state must start method is called, then the time is truly created a thread in the JVM, thread once started can perform now? The answer is no, or not running threads and processes have to reflexively defer to the same CPU scheduling, so we put this intermediate state into an executable state, that it has qualified to perform, but did not really execute, instead of waiting for CPU scheduling.

3, RUNNING state of the thread

Once selected thread queue by polling or CPU can perform tasks from other means, then the time it can really implement their own logic code, you need to point out that a state is RUNNING thread is in fact RUNNABLE, but in turn, It is not true.

In this state, the state of the thread may occur following a state transition.

  1. TERMINATED directly into the state, such as calling JDK has been deprecated stop method or determine a logical identity.
  2. Entered the BLOCKED status, such as call SLEEP, or wait to join the waitSet the method.
  3. Perform a blocking IO operations, such as read and write because of network data enters the BLOCKED state.
  4. Acquire a lock resources to be added to the lock of the blocking queue to enter the BLOCKED state.
  5. Since the CPU scheduler performs polling so that the thread to give proceeds RUNNABLE state.
  6. Thread the initiative to call yield method, to give up executive power CPU, enter RUNNABLE state.

 4, BLOCKED state of the thread

BLOCKED state when the thread is blocked, it can enter the following states:

  1. TERMINATED directly into the state, such as calling JDK has been deprecated stop method or JVMCrash
  2. Thread end blocking operation, such as reading the desired data bytes into RUNNABLE state.
  3. Thread finishes dormant specified time, into the state RUNNABLE
  4. Wait in the thread wakes up another thread notify / notifyall, enter RUNNABLE state.
  5. Thread gets to a certain lock resources into RUNNABLE state.
  6. Thread is interrupted in the course of obstruction, such as other thread calls interrupt method, enter RUNNABLE state.

 5, TERMINATED state of the thread

TERMINATED final state is a thread in this state, the thread will not switch to any other state, the thread into the Terminated state means that the whole life cycle of the end of the thread, the thread will enter the following Terminated state.

  1. Thread running normal end, the end of the life cycle.
  2. Thread running error ended unexpectedly
  3. JVM crash, leading all threads are finished.

3. What is the thread start method?

First: Thread start source code as follows:

public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

Source start method is simple enough, in fact, the core part is start0 the local method, that is, JNI method;

That method calls start0 start method, then the run overridden method is called when it?

In fact at the beginning of the implementation of this thread, JVM will call the run method of this thread, in other words, the run method is called JNI method start0, start to read the source code will summarize a few key points as follows knowledge.

  1. Thread NEW state is configured, in fact, the internal property threadStatus 0.
  2. You can not start two times Thread, otherwise there will be IllegalThreadStateException exception.
  3. After starting the thread will be added to a ThreadGroup in.
  4. The end of the life cycle of a thread is called again start to the terminated method is not allowed, that is to say Terminated state is no way back to runnable state.

The following code is executed:

import java.util.concurrent.TimeUnit;

public class A {
    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(10);
                }catch (Exception e) {
                    e.printStackTrace ();
                }
            }
        };
        thread.start();
        thread.start();
    }
}

At this point the program will throw

When we change the next code, that is, after the end of the life cycle, and re-called.

import java.util.concurrent.TimeUnit;

public class A {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(1);
                }catch (Exception e) {
                    e.printStackTrace ();
                }
            }
        };
        thread.start();
        TimeUnit.SECONDS.sleep(5);
        thread.start();
    }
}

We will find that the program will also throw illegalThread exception.

Note: Although the program will also throw an exception, but maybe these exceptions are essentially different.

  1. The first is because the repeat start, but not allowed to start the second time, but this time the thread is in the running state.
  2. The second attempt to reactivate the illegal status also throws an exception, but this time no thread because the thread of the life cycle has ended.

Through the above analysis we can see, the real thread of execution logic in the run method, usually we will become the method of execution units run thread.

If we do not rewrite the run, that run is an empty method.

Thread start of the run and is a more classic template design mode to write the code structure algorithm parent class, sub-class implements the logic details, here is a simple template design pattern.

package concurrent.chapter01;

public class TemplateMethod {
    public final void print(String message) {
        System.out.println("###");
        wrapPrint(message);
        System.out.println("###");
    }
    protected void wrapPrint(String message) {
        
    }
    public static void main(String[] args) {
        TemplateMethod t1 = new TemplateMethod() {
            @Override
            protected void wrapPrint(String message) {
                System.out.println("*"+message+"*");
            }
        };
        t1.print("Hello Thread");
        TemplateMethod t2 = new TemplateMethod() {
            @Override
            protected void wrapPrint(String message) {
                System.out.println("+"+message+"+");
            }
        };
        t2.print("Hello Thread");
    }
}

Results are as follows:

4, the following is a business lobby called the number machine simulation program

Suppose there are four numbers out of the machine, which means that there are four threads at work, let's look at the process simulation program called the number, the convention business day of receiving up to 50 pen, that number is up to 50 out of

code show as below:

package concurrent.chapter01;

public class TicketWindow extends Thread{
    private final String name;
    private static final int MAX = 50;
    private int index = 1;
    public TicketWindow(String name) {
        this.name=name;
    }
    @Override
    public void run() {
        while(index<=MAX) {
            . System OUT .println ( " counter: " + name + " The current number is: " + (index ++ ));
        }
    }
    public static void main(String[] args) {
        T1 TicketWindow = new new TicketWindow ( " early the 1st machine number " );
        t1.start();
        T2 TicketWindow = new new TicketWindow ( " early the 2nd machine number " );
        t2.start();
        T3 TicketWindow = new new TicketWindow ( " early the 3rd machine number " );
        t3.start();
        T4 TicketWindow = new new TicketWindow ( " early the 4th machine number " );
        t4.start();
    }
}

Results are as follows:

Obviously this is not what we want to see. How to improve it?

Here I will index variable is set to staic

Seemingly has improved. But the thread safety problems.

So Java provides an interface: Runnable designed to solve the problem, thread and business logic run completely separated.

5, Runnable interface and the introduction of policy mode

Runnalbe interface is very simple, but no definition of a method of run no return value parameter, the specific code is as follows:

public interface Runnable{
  void run();    
}

In many books, will say that there are two ways to create a thread, the first is to construct a Thread, the second is to achieve Runnable interface, this argument is wrong, at least it is not rigorous, in the JDK, on ​​behalf of the only thread thread class, we analyzed earlier, a thread of execution unit is run method, you can then override inherited thread run method to achieve their business logic, you can implement Runnable interface to achieve their business logic code as follows:

@override
public void run(){
   if(target!=null){
   target.run(); 
   }    
}

The above code snippet is the source Thread run method, from which we can go to understand, to create threads only one way, and that is the Thread class structure, and the realization of the thread execution unit there are two ways, first is a rewrite of Thread run method, the second method is to run implement Runnable and Thread Runnable examples of configuration parameters used.

Strategy Mode

In fact, whether it is run or the method of Runnable, Thread run method itself say that they want to control their own threads and run business logic separated achieve accountable, features a single principle, which is the GoF Design Patterns in strategy design pattern very similar.

JDBC to here as example:

package concurrent.chapter01;

import java.sql.ResultSet;

public interface RowHandler <T>{
    T handle(ResultSet set);
}

rowhandler only responsible for the interface from the database query result set out of operation, as the ultimate return to what kind of data structure, you need to realize their own, similar to the Runnable interface.

package concurrent.chapter01;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class RecordQuery {
    private final Connection connection;
    
    public RecordQuery(Connection connection) {
        this.connection = connection;
    }
    public<T> T query(RowHandler<T> handler,String sql,Object... params) throws SQLException{
        try(PreparedStatement stmt = connection.prepareStatement(sql)){
            int index = 1;
            for(Object param:params) {
                stmt.setObject(index++,param);
            }
            ResultSet resultSet = stmt.executeQuery();
            return handler.handle(resultSet);
        }
    }
}

The benefits of the above code is that you can use Query method to deal with any queries the database and returns the results of the different only because you pass different RowHandler differ, the same RecodeQuery only responsible for obtaining the data, while RowHanlder only responsible for processing the data, responsibilities seasons, each class are single function.

Override the run method of the Thread class and Runnable interface to achieve the run method can not be shared, that is to say A thread can not run as their own process B thread execution unit, and use the Runnable interface is very easy to achieve this i.e., using the same example of the configuration of a different instance of Runnable.

If you do not understand, look at the following code.

package concurrent.chapter01;

public class TicketWindowRunnable implements Runnable{
    private int index = -1;
    private final static int MAX = 50;
    @Override
    public void run() {
        while(index<=MAX) {
            . The System OUT .println (Thread.currentThread () + " number is: " + (index ++ ));
             the try {
                Thread.sleep(100);
            }catch (Exception e) {
                e.printStackTrace ();
            }
        }
    }
    public static void main(String[] args) {
        final TicketWindowRunnable task = new TicketWindowRunnable();
        WindowThread1 the Thread = new new the Thread (Task, " One Window " );
        Thread WindowThread2 = new Thread(task,"二号窗口");
        Thread WindowThread3 = new Thread(task,"三号窗口");
        Thread WindowThread4 = new Thread(task,"四号窗口");
        WindowThread1.start();
        WindowThread2.start();
        WindowThread3.start();
        WindowThread4.start();
    }
}

运行结果如下:

 

 惊不惊喜?

上面并没有对index进行static进行修饰,但是和上面被static修饰的是一个效果。原因是我们每次操作的都是同一个对象即task。

 

Guess you like

Origin www.cnblogs.com/godoforange/p/11008865.html