JAVA multi-thread

The basic concept of multithreading

A thread is an execution scenario in a process, that is, the execution process. What is the difference between a process and a thread?

• Each process is an application and has its own memory space

• Threads in the same process share memory and resources in the same process (shared memory is heap memory and method area memory, stack memory is not shared, each thread has its own.)

What is a process?

One process corresponds to one application. For example, if you start Word on the Windows operating system, you have started one

Process. When you start the JVM in a Java development environment, you start a process. Modern computers are more supportive

In the same operating system, multiple processes can be started at the same time.

What does multiple processes do?

A single-process computer can only do one thing.

Play a game (game progression) while listening to music (music progression) on your computer.

On a single-core computer, are game and music running at the same time at the same time? It isn’t.

Because a computer’s CPU can only do one thing at a time. As the computer will be in “game progress” and “music.

The frequent switching between the “progression” is performed at such high speed that the human feels the game and the music are going on simultaneously.

The purpose of multi-process is not to increase execution speed, but to increase CPU utilization.

Processes and memory between processes are independent.

What is a thread?

A thread is an execution scenario in a process. A process can start multiple threads.

What does multithreading do?

Multithreading is not about speed, it’s about application utilization.

Threads and threads share “heap memory and method area memory”, and stack memory is independent, one thread per stack.

Can give a real world human the illusion that multiple threads are executing concurrently.

How does a Java program work?

The Java command will start the Java VIRTUAL machine (JVM), which is equivalent to starting an application, which means starting a process. The process automatically starts a “main thread” that calls the main method of a class. So the main method runs in the main thread. All previous programs were single-threaded.

Thread life cycle

Threads are execution scenarios within a process, and a process can start multiple threads

Ready: After the start command is executed

Run: occupy CPU time

Block: When a WAIT statement is executed, a sleep statement is executed, and an object lock is waiting for input

Terminate: Exits the run() method

Multithreading is not about speed, it’s about application utilization.

Threads and threads share heap memory and method area memory. Stack memory is independent, one thread per stack.

Can give humans in the real world the illusion that multiple threads are executing concurrently.

Many people are confused about some of these concepts, such as synchronization, concurrency, etc. Let’s set up a data dictionary to avoid misunderstanding.

• Multithreading: When the program (a process) runs with more than one thread

• Parallelism and concurrency:

O Parallelism: The simultaneous execution of a piece of processing logic by multiple CPU instances or machines is truly simultaneous.

O Concurrency: Through the CPU scheduling algorithm, the user appears to execute simultaneously, but is not really simultaneous from the CPU operation level. Concurrency often has a common resource in the scene, so there is a bottleneck for this common resource, we will use TPS or QPS to reflect the processing capacity of the system.

Thread safety: Often used to describe a piece of code. In the case of concurrency, the code is used by multiple threads, the order in which the threads are scheduled does not affect any results. This time to use multithreading, we only need to pay attention to the system’s memory, CPU is not enough. Conversely, thread insecurity means that the order in which threads are scheduled affects the final result, such as a transaction-free transfer code:

VoidtransferMoney (Userfrom, Userto floatamount) {

To.. setMoney (to.. the getBalance () + amount);

From the setMoney (from the getBalance () – the amount).

}

Synchronization: Synchronization in Java refers to the use of artificial control and scheduling to ensure that multi-threaded access to shared resources becomes thread-safe to ensure accurate results. Simply add the @synchronized keyword in the code above. A good program is one that improves performance while ensuring accurate results. Thread safety takes precedence over performance.

The Java command will start the Java VIRTUAL Machine. Starting the JVM, which is equivalent to starting an application, will start a process, which will automatically start a “main thread”,

The main thread then calls the main() method of a class, so the main() method runs in the main thread.

Thread scheduling model can be divided into time-sharing scheduling model and preemptive scheduling model. Java uses preemptive scheduling model

Typically, our computer has only one CPU, which can execute only one instruction at a time, and threads can execute instructions only if they are given a slice of CPU time, which is usage. Threads do not run in parallel on a single-CPU machine; they can only run in parallel on multiple cpus. Java virtual machine is responsible for thread scheduling and CPU usage. There are two scheduling models: time-sharing scheduling model and preemptive scheduling model. Java uses preemptive scheduling model. Time-sharing scheduling model: all threads take turns to use the CPU and evenly allocate the CPU time slices occupied by each thread. Preemptive scheduling model: Priority is given to threads with higher priority to use CPU. If threads have the same priority, one thread will be randomly selected, and the thread with higher priority gets more CPU time slices.

According to the time-sharing scheduling model, all threads take turns using the CPU, allocating the CPU time slice for each thread equally

According to a preemptive scheduling model, threads with a higher priority are given priority to use the CPU. If they have the same priority, one thread is randomly selected, and the thread with a higher priority gets more CPU slices.

PublicclassThreadTest {

Publicstaticvoidmain (String [] args) {

ThreadTest1 ();

/ / ThreadTest2 ();

/ / ThreadTest3 ();

/ / ThreadTest4 ();

/ / ThreadTest5 ();

}

/ * *

* get the currentThread object: thread.currentthread (); Name the thread t1.setName(“t1”); Get the name of the thread:

* t.g etName ();

* /

PrivatestaticvoidThreadTest1 () {

Threadt = Thread. CurrentThread (); // the thread to which the memory address is stored is the main thread.

System. The out. Println (t.g etId ());

Threadt1 = newThread (newProcessor1 ());

// Give the thread a name

T1. Elegantly-named setName (” t1 “);

T1. Start ();

Threadt2 = newThread (newProcessor1 ());

T2. Elegantly-named setName (” t2 “);

T2. Start ();

}

/ * *

* A thread with a higher priority obtains more CPU time slices. Priority :1-10 Minimum :1 Maximum :10 Default :5

* /

PrivatestaticvoidThreadTest2 () {

Threadt1 = newProcessor2 ();

Threadt2 = newProcessor2 ();

T1. Elegantly-named setName (” t1 “);

T2. Elegantly-named setName (” t2 “);

System. The out. Println (t1) getPriority ());

System. The out. Println (t2) getPriority ());

T1. SetPriority (1);

T2. SetPriority (10);

T1. Start ();

T2. Start ();

}

/ * *

* 1. Thread. Sleep (ms); Sleep () is a static method. Sleep () blocks the current thread, freeing CPU for another thread

* /

PrivatestaticvoidThreadTest3 () {

Threadt = newThread (newProcessor3 ());

T.s tart ();

For (inti = 0; i<11; i++){

System. Out.println (Thread. CurrentThread (). The getName () + “= = = = = = = = >”

+ I);

Try {

T.s leep (5000); // Equivalent to thread.sleep (5000); It still blocks the current thread, regardless of the T thread.

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

}

}

/ * *

* If a thread is sleeping, how do I break its sleep by using the exception handling mechanism

* /

PrivatestaticvoidThreadTest4 () {

Try {

Threadt = newThread (newProcessor4 ());

T.s tart ();

Thread.sleep (5000); / / sleep 5 s

T.i nterrupt (); // Interrupt Thread’s sleep

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

}

/ * *

* How to correctly and better terminate an executing thread requirement: the thread terminates after 5s startup.

* /

PrivatestaticvoidThreadTest5 () {

Processor5p = newProcessor5 ();

Threadt = newThread (p);

T.s tart ();

// Terminate after 5s

Try {

Thread.sleep (5000);

P.i sRun = false;

{} the catch (InterruptedExceptione)

/ / TODOAuto – generatedcatchblock

E.p rintStackTrace ();

}

}

}

ClassProcessor1implementsRunnable {

@ Override

Publicvoidrun () {

Threadt = Thread. CurrentThread (); //t store memory address to point to “t1 thread object”

System. The out. Println (t.g etName ());

System. The out. Println (t.g etId ());

}

}

ClassProcessor2extendsThread {

@ Override

Publicvoidrun () {

For (inti = 0; i<50; i++){

System. Out.println (Thread. CurrentThread (). The getName ()

+ “– — — — — — — — — — – >” + I);

}

}

}

ClassProcessor3implementsRunnable {

/ * *

* The run method in Thread cannot throw an exception, so after overriding the RUNn method, throws cannot be used at the declared location of the run method

* So exceptions in the run method can only be tried… catch…

* /

@ Override

Publicvoidrun () {

For (inti = 0; i<11; i++){

System. Out.println (Thread. CurrentThread (). The getName () + “= = = = = = = = >”

+ I);

Try {

Thread.sleep (1000);

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

}

}

}

ClassProcessor4implementsRunnable {

@ Override

Publicvoidrun () {

Try {

Thread.sleep (1000000000);

System.out.println(” Can I execute here “);

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

For (inti = 0; i<11; i++){

System. Out.println (Thread. CurrentThread (). The getName () + “= = = = = = = = >”

+ I);

}

}

}

ClassProcessor5implementsRunnable {

BooleanisRun = true;

@ Override

Publicvoidrun () {

For (inti = 0; i<11; i++){

If (isRun) {

Try {

Thread.sleep (1000);

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

System. Out.println (Thread. CurrentThread (). The getName ()

+ “= = = = = = = = >” + I);

}

}

}

}

Thread priority

There are three main thread priorities: MAX_PRIORITY(the highest); MIN_PRIORITY (minimum) NORM_PRIORITY(standard) Default

// Set the priority of the thread. The priority cannot be set again after the thread is started

// Priority must be set before startup

// Set the highest priority

T1. SetPriority (Thread. MAX_PRIORITY);

sleep

PublicclassSleepTest {

Publicstaticvoidmain (String [] args) {

System. The out. Println (” Wait “);

// Make the main thread wait 5 seconds before executing

Wait. BySec (5);

// Prompt to resume execution

System. The out. Println (” start “);

}

}

ClassWait {

PublicstaticvoidbySec (longs) {

/ / sleeps a 1 second

For (inti = 0; i<s; i++){

System. The out. Println (I + 1 + “seconds”);

Try {

/ / sleep1 seconds

Thread.sleep (1000);

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

}

}

}

Stopping a thread

Anyway, if our thread is sleeping, we can interrupt it using an interrupt

A queue usually defines a tag to stop a thread’s execution based on the status of the tag

yield

It is similar to sleep(), except that the user cannot specify how long to pause, and yield() allows only threads of the same priority to execute, while yieid allows CPU usage to be ceded to threads of the same priority

PublicclassYieldTest {

Publicstaticvoidmain (String [] args) {

FirstThreadmt = newFirstThread ();

SecThreadmnt = newSecThread ();

Mt. Start ();

MNT start ();

}

}

ClassFirstThreadextendsThread {

Publicvoidrun () {

For (inti = 0; i<5; i++){

System.out.println(” first thread’s first “+(I +1)+” run “);

Thread. The yield (); // Suspend the thread

}

}

}

ClassSecThreadextendsThread {

Publicvoidrun () {

For (inti = 0; i<5; i++){

System.out.println(” the first “+(I +1)+” run “of the second thread);

Thread. The yield ();

}

}

}

The join

The current thread can call the join method of another thread. After the call, the current thread will be blocked and will not execute until the called thread finishes executing

PublicclassJoinTestextendsThread {

PublicJoinTest (Stringname) {

Super (name);

}

Publicvoidrun () {

For (inti = 0; i<5; i++)

System. The out. Println (getName () + “” + I);

}

Publicstaticvoidmain (String [] args) {

For (inti = 0; i<10; i++){

If (I = = 5) {

JoinTesttempjt=newJoinTest(” Threadjoin “);

Try {

Tempjt. Start ();

Tempjt. The join ();

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

}

System. The out. Println (Thread. CurrentThread (). The getName () + “” + I);

}

}

}

synchronized

Thread synchronization, refers to a certain moment, refers to allow a thread to access to a Shared resource, thread synchronization object is to lock, if the object is the method in the synchronization method, so can only execute a method at a certain moment, use of thread synchronization to solve above problems, we just make sure the thread operation s, thread 2 do not allow the operation, Only after thread one uses s, let thread two use the s variable

• Asynchronous programming model: T1 threads execute T1, T2 threads execute T2, and neither one waits between the two threads.

• Synchronous programming model: T1 thread and T2 thread execute. T2 thread must wait for T1 thread to finish execution before T2 thread can execute. This is synchronous programming model.

• When to use sync? Why introduce thread synchronization?

• 1. For data security, thread synchronization must be added in order to ensure data security, even though application utilization is reduced.

• Thread synchronization makes the application (equivalent to) single threaded.

• 2. Under what conditions should thread synchronization be used?

• Number one: it must be multithreaded

• Second: multi-threaded environments share the same data.

• Third: Shared data involves modification operations.

//synchronized is used to lock objects

Use synchronized to synchronize only thread-safe code

// Synchronized blocks are preferred

// Because the more code that is synchronized, the longer it takes to execute, the longer other threads wait

// Impact efficiency

PublicclassTestWithdrawal {

Publicstaticvoidmain (String [] args) {

// Create two threads

TestAccountr = newTestAccount ();

Threadone = newThread (r);

Threadtwo = newThread (r);

One. The elegantly-named setName (” * * “);

SetName (” Zhang SAN’s wife “);

// Start the thread

One. The start ();

Two start ();

}

}

ClassAccount {

Privateintbalance = 500; / / the balance

PublicintgetBalance () {

Returnbalance;

}

/ / withdrawals

Publicvoidwithdraw (intamount) {

The balance = the balance – the amount;

}

}

ClassTestAccountimplementsRunnable {

All threads created with the TestAccount object share the same account object

PrivateAccountacct = newAccount ();

Publicvoidrun () {

For (inti = 0; i<5; i++){

MakeWithdrawal (100); / / withdrawals

If (acct. The getBalance () < 0) {

System.out.println(” account overdrawn!” );

}

}

}

PrivatevoidmakeWithdrawal (intamt) {

Synchronized (acct) {

If (acct. The getBalance () > = amt) {

System.out.println(thread.currentThread ().getName());

Try {

Thread.sleep (500); // Withdraw after 0.5 seconds

{} the catch (InterruptedExceptionex)

}

// If the balance is sufficient, withdraw the money

Acct. Withdraw (amt);

System.out.println(thread.currentThread ().getName()+” +acct.getBalance() “);

} else {

// Prompt for insufficient balance

System.out.println(” The balance is insufficient to pay “)

+ thread.currentThread ().getName();

+ acct. The getBalance ());

}

}

}

}

A deadlock

PublicclassDeadLock {

Publicstaticvoidmain (String [] args) {

Objecto1 = newObject ();

Objecto2 = newObject ();

Threadt1 = newThread (newT1 (o1, o2));

Threadt2 = newThread (newT2 (o1, o2));

T1. Start ();

T2. Start ();

}

}

ClassT1implementsRunnable {

Objecto1;

Objecto2;

T1 (Objecto1 Objecto2) {

This. O1 = o1;

O2 = o2; this.

}

@ Override

Publicvoidrun () {

Synchronized (o1) {

Try {

Thread.sleep (1000);

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

Synchronized (o2) {

}

}

}

}

ClassT2implementsRunnable {

Objecto1;

Objecto2;

T2 (Objecto1 Objecto2) {

This. O1 = o1;

O2 = o2; this.

}

@ Override

Publicvoidrun () {

Synchronized (o2) {

Try {

Thread.sleep (1000);

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

Synchronized (o1) {

}

}

}

}

Daemon thread

From the thread classification can be divided into: user thread (above is the user thread), the other is the daemon thread. Daemon thread is that all end user threads of life cycle, daemon thread to the end of the life cycle, as long as there is a user thread exists, then daemon thread will not end, Java, for example the famous garbage collector is a daemon thread, only the application all threads in the end, it will end.

• The daemon thread exits when all other user threads terminate!

• Daemon threads typically execute indefinitely.

PublicclassDaemonThread {

ThrowsInterruptedException publicstaticvoidmain (String [] args) {

Threadt1 = newThread (newRunnable2 ());

T1. Elegantly-named setName (” t1 “);

// Change the user thread t1 to a daemon thread. The following parameters can be modified when the thread is not started

T1. SetDaemon (true);

T1. Start ();

/ / main thread

For (inti = 0; i<10; i++){

System. The out. Println (Thread. CurrentThread (). The getName () + “– — — — – >” + I);

Thread.sleep (1000);

}

}

}

ClassRunnable2implementsRunnable {

@ Override

Publicvoidrun () {

Inti = 0;

While (true) {

I++;

System. Out.println (Thread. CurrentThread (). The getName () + “– — — — — — – >”

+ I);

Try {

Thread.sleep (500);

{} the catch (InterruptedExceptione)

E.p rintStackTrace ();

}

}

}

}

When the main thread is finished, the daemon thread does not finish the output of all data, that is, the daemon thread serves the user thread. When the user thread is finished, the daemon thread will terminate automatically

The Timer. The schedule ()

/ * *

* About the application of timers: execute a piece of code at a fixed interval

* /

PublicclassTimerTest {

ThrowsParseException publicstaticvoidmain (String [] args) {

//1. Create a timer

Timert = newTimer ();

//2. Specify a scheduled task

T.s chedule (newLogTimerTask (), newSimpleDateFormat (

“Yyyy – MM – ddHH: MM: ssSSS”). The parse (” 14:24:00 000 2017-06-29 “),

10 * 1000);

}

}

// Specify a task

ClassLogTimerTaskextendsTimerTask {

@ Override

Publicvoidrun () {

System. Out.println (newSimpleDateFormat (” yyyy – MM – ddHH: MM: ssSSS “)

The format (newDate ()));

}

}

I’m Melon, a 10-year programming driver. Q I 3474203856. Leave a message to Melon or say you read the article. All relevant technical questions can be answered together.