Multi-thread in the Java program

zhaozj2021-02-08  316

Why is it waiting in line? The following simple Java program completes four unrelated tasks. Such a program has a single control thread that controls linearly between the four tasks. Also, because the resources required - printers, disks, databases, and display - Due to the inherent latency of hardware and software, each task contains significant wait time. Therefore, the program must wait for the printer to complete the task of the print file before accessing the database, and so on. If you are waiting for the completion of the program, this is a bad use of computing resources and your time. One way to improve this procedure is to make it a multi-thread.

Four irrelevant tasks

Class myclass {

Static Public Void Main (String Args []) {

Print_a_file ();

MANipulate_another_file ();

Access_database ();

Draw_picture_on_screen ();

}

} In this example, each task must wait for the previous task before the start, even if the task involved is not related. However, in real life, we often use multithreaded models. We can also let children, spouses and parents complete other tasks while dealing with certain tasks. For example, I may send my son to the post office to buy a stamp. This is called a plurality of control (or execution) threads with software terms. You can use two different ways to get multiple control threads:

Multiple processes can create multiple processes in most operating systems. When a program is started, it can create a process for each task that is about to start and allows them to run at the same time. When a program is blocked by waiting for network access or user input, another program can also operate, which increases resource utilization. However, in this way, create each process to pay a certain price: Set a process to occupy a considerable part of the processor time and memory resources. Moreover, most operating systems do not allow the process to access memory space for other processes. Therefore, communication between processes is inconvenient, and it will not provide itself to an easy programming model. Thread thread is also called light processes (LWP). Because the thread can only be active in the scope of a single process, it is cheaper than the creation process. Thus, because the thread allows collaboration and data exchange, it is very cheap in the calculation resource, thread is more desirable than the process. The thread requires the support of the operating system, so it is not all the machines to provide a thread. Java programming language, as a quite new language, has been integrated with the thread support and language itself, which provides a strong support for threads.

Using the Java programming language to implement thread Java programming languages ​​make multi-threads so simple and valid, so that some programmers say it is actually natural. Although the use of threads in Java is much easier than in other languages, there are still some concepts to be mastered. An important thing to remember is the main () function is also a thread and can be used for useful work. Programmers only need to create new threads when needing multiple threads. The Thread THREAD class is a specific class, ie not an abstract class, which encapsulates the behavior of threads. To create a thread, the programmer must create a new class exported from the Thread class. The programmer must override the thread's Run () function to complete useful work. The user does not call this function directly; but must call the Start () function of Thread (), the function calls Run (). The following code illustrates its usage: Create two new threads

Import java.util. *;

Class Timeprinter Extends Thread {

Int PauseTime;

String name;

Public TimePrinter (int x, string n) {

Pauseetime = x;

Name = n;

}

Public void run () {

While (true) {

Try {

System.out.println (Name ":" New

Date (System.currentTimeMillis ()));

Thread.sleep (Pauseetime);

} catch (exception e) {

System.out.println (e);

}

}

}

Static Public Void Main (String Args []) {

TimePrinter TP1 = New Timeprinter (1000, "Fast Guy");

TP1.START ();

TimePrinter TP2 = New Timeprinter (3000, "Slow Guy");

Tp2.start ();

}

} In this example, we can see a simple program that displays the current time on the screen by two different time intervals (1 second and 3 seconds) on the screen. This is done by creating two new threads, including main () total three threads. However, because sometimes the class to run as a thread may be part of a certain level, it is no longer possible to create threads according to this mechanism. Although any number of interfaces can be implemented in the same class, Java programming languages ​​only allow one class to have a parent class. At the same time, some programmers avoid export from the Thread class because it imparts classes. For this situation, you need a Runnable interface. Runnable Interface This interface has only one function, Run (), this function must be implemented by a class that implements this interface. However, it is slightly different from the previous example with the previous example. We can rewrite the previous example with the Runnable interface. (Different parts are expressed in black body.)

Create two new threads without strong plus class level

Import java.util. *;

Class Timeprinter Implements Runnable {

Int PauseTime;

String name;

Public TimePrinter (int x, string n) {

Pauseetime = x;

Name = n;

}

Public void run () {

While (true) {

Try {

System.out.println (Name ":" New

Date (System.currentTimeMillis ()));

Thread.sleep (Pauseetime);

} catch (exception e) {

System.out.println (e);

}

}

}

Static Public Void Main (String Args []) {

Thread T1 = New Thread (New TimePrinter (1000, "Fast Guy"));

T1.Start ();

Thread T2 = New Thread (New TimePrinter (3000, "Slow Guy"));

T2.Start ();

}

} Please note that when using the runnable interface, you cannot create the object you need and run it; you must run it within an instance of the Thread class. Many programmers prefer Runnable interface because inheritance from Thread class will impose class level. Synchronized keywords so far, what we see is only used in a very simple way. Only the smallest data stream, and no two threads accesses the same object. However, in most useful programs, there is usually a stream between threads. Try considering a financial application, there is an Account object, as shown in the following example: A number of activities in a bank PUBLIC CLASS Accent {

String Holdername;

Float Amount;

Public Account (String Name, Float AMT) {

Holdername = name;

Amount = AMT;

}

Public void deposit (float AMT) {

Amount = AMT;

}

Public void withdraw (float AMT) {

Amount - = AMT;

}

Public float checkbalance () {

Return Amount;

}

} Late an error in this code sample. If this class is used for single-threaded applications, there will be no problems. However, in the case of multi-threaded applications, different threads may also access the same Account object, such as a joint account accessible to different ATMs. In this case, deposit and expenditure may occur in this way: a transaction is covered by another transaction. This situation will be catastrophic. However, Java programming languages ​​provide a simple mechanism to prevent this coverage. Each object has an associated lock at runtime. This lock can be obtained by adding a keyword Synchronized to a method. In this way, the revised Account object (as shown below) will not suffer such an error like data corruption: Synchronize multiple activities in a bank.

Public class account {

String Holdername;

Float Amount;

Public Account (String Name, Float AMT) {

Holdername = name;

Amount = AMT;

}

Public synchronized void deposit (float AMT) {

Amount = AMT;

}

Public synchronized void withdraw (float AMT) {

Amount - = AMT;

}

Public float checkbalance () {

Return Amount;

}

} Deposit () and the withdraw () function require this lock to operate, so another function is blocked when a function is running. Please note that checkbalance () is not changed, it is strictly a read function. Because checkbalance () is not synchronous, any other method will not block it, and it does not block any other method, whether or not those methods are synchronized.

The advanced multi-threaded support thread group threads in the Java programming language is individually created, but they can classify them into the thread group to facilitate debugging and monitoring. You can only associate it with a thread group while creating a thread. In programs that use a large number of threads, use thread group organization threads may be helpful. They can be considered as a directory and file structure on a computer. Inter-threaded information When the thread is waiting to wait for a condition before continuing execution, only the synchronized keyword is not enough. Although the Synchronized keyword blocks concurrently updated an object, it does not implement the thread. The Object class provides three functions for this: Wait (), Notify () and NotifyAll (). Take the global climate prediction procedure as an example. These programs are divided into many units in each loop by dividing the earth, and each unit is calculated until these values ​​tend to stabilize, and then some data is exchanged between adjacent cells. Therefore, from essentially, each thread in each cycle must wait for all threads to complete their tasks to enter the next loop. This model is called mask synchronization, the following example shows this model: Mask Synchronous Public Class Bsync {

INT TOTALTHREADS;

Int CurrentThreads;

Public BSYNC (INT X) {

TotalthReads = x;

CurrentThreads = 0;

}

Public synchronized void waitforall () {

CurrentThreads ;

CurrentThreads

Try {

Wait ();

} catch (exception e) {}

}

Else {

CurrentThreads = 0;

NotifyAll ();

}

}

} When Wait () is called for a thread, the thread is effectively blocked, and only the other thread calls notify () or notifyAll () until the same object. Therefore, in the previous example, different threads will call the waitforlL () function after completing their work, and the last thread will trigger the NotifyAll () function, which will release all threads. The third function notify () only informs a thread that is waiting for, this function is useful when accessing the resource used by a thread can be accessed. However, it is impossible to predict which thread will get this notification because it depends on the Java Virtual Machine (JVM) scheduling algorithm. When the CPU gives another thread to abandon a rare resource (such as database connection or network port), it may call the Yield () function to temporarily reduce its priority so that some other threads can run. The daemon has two types of threads: user threads and daemons. The user thread is those threads that complete useful work. Guarding threads are threads that only provide auxiliary function. The THREAD class provides a setDaemon () function. The Java program will run to all user threads, and then it will destroy all the daemons. In the Java Virtual Machine (JVM), even after the MAIN is over, if another user thread is still running, the program can continue to run.

The way to avoid not advocating the use is to support those methods reserved backward compatibility, which may appear in future versions or may not appear. Java multi-threaded support has made significant revisions in version 1.1 and version 1.2, and STOP (), Suspend () and resume () functions are not advocated. These functions may introduce subtle errors in the JVM. Although the function name may sound attracted, please call the temptation not to use them.

Debugging threaded procedures In threaded programs, certain common and annoying conditions that may happen are deadlocks, lock, memory damage, and resource depletion. The deadlock deadlock may be the most common problem of multi-threaded procedures. When a thread requires a resource while another thread holds the lock of the resource, a deadlock occurs. This situation is usually difficult to detect. However, the solution is quite good: all resource locks are obtained in the same order in all threads. For example, if there are four resources -a, b, c, and d - and a thread may get the lock of any of the four resources, make sure you first get the lock of A before getting the lock of B. Such push. If "thread 1" wants to get the lock of B and C, "Thread 2" acquires the lock of A, C, and D, which can cause blocking, but it will never cause death in these four locks. lock. Lock When a thread is busy accepting new tasks, it will never have a chance to complete any tasks, there will be live locks. This thread will eventually exceed the buffer and cause the program to crash. Imagine a secretary to enter a letter, but she has been busy answering the phone, so this letter will never be entered. Memory damage If you use the Synchronized keyword inefficient, you can avoid memory of this madness. Resources run out of certain system resources are limited, such as file descriptors. Multi-threaded programs may deplete resources because each thread may wish to have such resources. If the number of threads is quite large, or the number of candidates for a resource far exceeds the number of available resources, it is best to use the resource pool. One of the best examples is the database connection pool. As long as the thread needs to use a database connection, it takes one from the pool and returns it back to the pool. The resource pool is also called a repository. Debugging a large number of threads Sometimes a program is extremely difficult because there are a lot of threads running. In this case, this class below may be manually used:

Public class probe extends thread {

Public probe () {}

Public void run () {

While (true) {

Thread [] x = new thread [100];

Thread.Enumerate (X);

For (int i = 0; i <100; i ) {

Thread t = x [i];

IF (t == null)

Break;

Else

System.out.println (T.GetName () "/ T" T.GetPriority ()

"/ t" T.isalive () "/ t" t.isdaemon ());

}

}

}

}

Limiting thread priority and scheduling Java thread model involves thread priorities that can be dynamically changed. Essentially, the thread priority is a number between 1 and 10, the larger the number, the more urgent task. The JVM standard first calls a higher priority thread and then calls a lower priority thread. However, this standard is randomly processed for a thread having the same priority. How to deal with these threads depends on the operating system strategy of the base layer. In some cases, the priority thread is running at time; in other cases, the thread will run until the end. Keep in mind that Java supports 10 priorities. The priority supported by the grassroots operating system may have much less, which will cause some confusion. Therefore, the priority can only be used as a very rough tool. The final control can be done by smartly using the Yield () function. Typically, do not rely on thread priority to control the status of the thread.

Small junctions illustrate how to use threads in the Java program. A more important issue like a thread should be used on a large program depends on the hand of the hand. A way to determine if multiple threads in the application is to estimate the amount of code that can run in parallel. And remember the following: Using multithreading does not increase the capacity of the CPU. However, if the local thread implementation of JVM is implemented, different threads can run simultaneously on different processors (in the machine in multi-CPU), so that the multi-CPU machine is fully utilized. If the application is a computing intensive and is restricted by the CPU function, only multiple CPU machines can benefit from more threads. When the application must wait for a slow resource (such as a network connection or database connection), or when the application is non-interactive, multi-threading is usually advantageous. The Internet-based software is necessary to be multi-threaded; otherwise, the user will reflect the feeling of sensation. For example, multiple threads can make programming easier when developing a server-supported server. In this case, each thread can be a different customer or customer group service, thereby shortening the response time. Some of the programmers may have used threads in C and other languages, and there is no language support for threads in those languages. These programmers may usually have to lose confidence in threads.

转载请注明原文地址:https://www.9cbs.com/read-826.html

New Post(0)