inherit thread class:
In Java, the support for multithreading technology is brought in. Inherit thread and implement the Runnable interface. Look at the results of the thread class first, as follows:
Public class Thread implements Runnable
It is found from the above code that the thread class implements the Runnable interface, which has a polymorphic relationship.
The limitation of this approach is not to support multiple inheritance, because Java is a single inheritance, so for multiple inheritance, the Runnable interface can be implemented completely.
Inheritance on one side, but the two methods of creating threads at work are the same in nature, without essential distinction.
public class Mythread extends thread{
@Override public
void Run () {
super.run ();
System.out.println ("Mythread");
}
public class Run {public
static void Main (string[] args) {
mythread mythread = new Mythread ();
Mythread.start ();
System.out.println ("Run over!");
}
The application of the code results:
From the graph results, the Run method of the Mythread class is executed later, which also shows that when using multithreaded technology, the execution result of the code is independent of the order of the code or the sequence of code calls.
Java.lang.IllegalThreadStateException exception occurs if the start () method is called more than once
The above describes the random invocation of a thread, and the following example shows the randomness of the thread:
Create a custom thread class Mythread.java with the following code:
public class Mythread extends thread{
@Override public
void Run () {
super.run ();
for (int i=0;i<10;i++) {
int time = (int) (Math.random () *1000);
try {
thread.sleep (time);
System.out.println ("run=" +thread.currentthread (). GetName ());
catch (Interruptedexception e) {
e.printstacktrace ();}}}
To create a run class again:
public class Run {public
static void Main (string[] args) {
mythread mythread = new Mythread ();
Mythread.setname ("Mythread");
Mythread.start ();
for (int i=0;i<10;i++) {
int time = (int) (Math.random () *1000);
try {
thread.sleep (time);
System.out.println ("main=" +thread.currentthread (). GetName ());
catch (Interruptedexception e) {
e.printstacktrace ();}}}
In the code, in order to show that the thread is random, use the form of random numbers to get a hang effect, which shows the uncertainty of which thread the CPU executes.
The start () method of the thread class notifies the thread planner that this thread is ready to wait for the call thread object's Run () method. The process is to have the system schedule a time to invoke the run () method in thread, which is to get the thread to run, and the startup thread has the effect of executing asynchronously. If the calling code Thread.run () is not executed asynchronously, it is synchronized. This thread object is not handed over to the thread planner for processing, but is invoked by the main main thread to invoke the run () method, which means that the code in the Run () method must be executed before executing the following code.
The effect of running asynchronously is as follows:
Also note that the order in which the start () method is executed does not represent the order in which the thread starts.
The thread class code is as follows:
public class TheadT1 extends thread{
private int i;
Public TheadT1 (int i) {
this.i = i;
}
public void Run () {
System.out.println (i);
}
}
Execute Class Code:
public class Theadt1test {public
static void Main (string[] args) {
TheadT1 t1 = new TheadT1 (1);
TheadT1 t2 = new TheadT1 (2);
TheadT1 t3 = new TheadT1 (3);
TheadT1 T4 = new TheadT1 (4);
TheadT1 T5 = new TheadT1 (5);
T1.start ();
T2.start ();
T3.start ();
T4.start ();
T5.start ();
}
The application results of the program are as follows:
implement Runnable Interface:
If you want to create a thread class that already has a parent class, you can only implement multithreaded functionality by implementing the Runnable interface.
Create a class that implements the Runnable interface with the following code:
The public class Myrunnable implements runnable{
@Override
the public void Run () {
System.out.println (" Myrunnable ");
}
}
public class Runnablerun {public
static void Main (string[] args) {
myrunnable run = new myrunnable ();
Thread t = new thread (run);
T.start ();
System.out.println ("End of Application!");
}
Application results:
Developing multithreaded applications in a way that uses the thread class is designed to be limited, because Java is a single inheritance, so in order to change this limitation, you can use the Runnbale interface as a way to implement multithreading techniques.
instance variables and thread safety:
Instance variables in custom thread classes can be shared and unshared to other threads, which is an important technical point to interact with multiple threads.
(1) Do not share the data:
View the data not shared by one of the following examples.
The sample code is as follows:
public class Sharedisnothread extends thread{
private int count = 5;
Public Sharedisnothread (String name) {
this.setname (name);
}
@Override public
Void Run () {
super.run ();
while (count>0) {
count--;
System.out.println ("by" +thread.currentthread (). GetName () + "computed, count=" +count);
}} public class Sharedisnothreadtest {public
static void Main (string[] args) {
Sharedisnothread t1 = new SHAREDISN Othread ("A");
Sharedisnothread t2 = new Sharedisnothread ("B");
sharedisnothread t3 = new Sharedisnothread ("C");
T1.start ();
T2.start ();
T3.start ();
}
The results of the operation are shown below:
The program shows that a total of 3 threads have been created, each with its own count variable, which reduces the value of its own count variable. In this case, the variable is not shared, and the example does not have multiple threads accessing the same instance variable.
(2) Sharing of data
The data is shared as shown in the following illustration:
Shared data is where multiple threads can access the same variable, such as when the polling function is implemented, multiple threads can handle the same person's votes at the same time.
Let's look at data sharing with an example:
public class Sharedthread extends thread{
private int count = 5;
@Override public
Void Run () {
super.run ();
while (count>0) {
try {
thread.sleep (1000);
} catch (Interruptedexception e) {
e.printstacktrace () ;
}
count--;
System.out.println ("by" +thread.currentthread (). GetName () + "computed, count=" +count);
}} public class Sharedthreadtest {public
static void Main (string[] args) {
Sharedthread sharedthread = new Sharedt Hread ();
thread T1 = new Thread (sharedthread, "A");
Thread t2 = new Thread (sharedthread, "B");
thread t3 = new Thread (sharedthread, "C");
T1.start ();
T2.start ();
T3.start ();
}
Sleep for a second, for the situation to appear more easily.
The results of the operation are shown below:
From the output, there is a negative number, resulting in a "non-thread-safe" problem. And we want to print the result is not repeated, but in descending order and the minimum is equal to 0.
In some JVMs, I operations are divided into 3 steps:
(1) Obtain the original I value.
(2) Calculating i-1.
(3) To assign the value of I.
And in our program there is a while to judge this step. If multiple thread accesses are present, there is a certain problem of non threading security.
In fact, this example is a typical sales scene: 3 salespeople, each salesperson can not come up with the same amount of the remaining quantity, must be sold after each salesperson, the other sales staff can continue to reduce the number of new items on the remaining 1 operations. This is the time to synchronize between multiple threads, that is, in order to reduce the 1 operation. Change the code as follows:
public class Sharedthread extends thread{
private int count = 5;
@Override
synchronized public void Run () {
super.run ();
while (count>0) {
try {
thread.sleep (1000);
} catch (Interruptedexception e) {
e.printstacktrace () ;
}
count--;
System.out.println ("have" +thread.currentthread (). GetName () + "computed, count=" +count);}}
When you rerun the program, no negative numbers and values are present.
Join the synchronized keyword before the Run method, so that multiple threads execute the Run () method in a queued manner. When a thread calls the Run method, it first determines whether the run method is locked, such as locking, indicating that another thread is calling the Run method, and that the Run method must be called when other threads have finished calling the Run method call. This also achieves the purpose of queuing to invoke the Run method, and achieves the effect of reducing the count variable by 1 in order. The synchronized keyword can be locked on any object and method, and the code that is locked is called a "mutex" or "Critical" section. When a thread wants to execute code in a synchronized code block, the thread first attempts to acquire the lock, and if it can get the lock, the thread can execute the code in the synchronized code block. If you can't get the lock, the thread will try to hold the lock until it gets there, and there are multiple threads competing for the lock. The following diagram of the process:
Note the exceptions to i--and System.out.println ():
The above describes the use of the synchronized keyword to solve the problem of non thread security, here through the program case to refine the println () method and i++ use when the "possible" another exception, and explain why. The sample code is as follows:
public class Mythread extends thread{
private int i = 5;
@Override public
Void Run () {
super.run ();
System.out.println ("i=" + (i--) + "Threadname=" +thread.currentthread (). GetName ());
}
public class Run {public
static void Main (string[] args) {
mythread thread = new Mythread ();
thread T1 = new thread (thread);
Thread t2 = new Thread (thread);
thread t3 = new thread (thread);
thread T4 = new thread (thread);
Thread T5 = new Thread (thread);
T1.start ();
T2.start ();
T3.start ();
T4.start ();
T5.start ();
}
Results of program execution:
The use case for this test is that although the println () method is internally synchronized, the i--operation is performed before entering the method, so there is a probability of a problem that occurs that is not thread safe.
Therefore, to prevent a problem that is not thread-safe, you still need to continue using the synchronization method. The CurrentThread () method CurrentThread () method returns information about which thread the code snippet is being invoked. The following is illustrated by an example. Specifically as follows:
public class Run {public
static void Main (string[] args) {
System.out.print (Thread.CurrentThread (). GetName ()) ;
}
}
Run Result:
The result shows that the main method is called by a thread named Main.
Continue with the experiment and create the following code:
public class Mythread extends thread{public
mythread () {
System.out.println ("Construction method Print:" +thread.currentthread (). GetName ());
@Override public
Void Run () {
System.out.println ("Print of the Run Method:" +thread.currentthread (). GetName ());
}
Public
class Run {public
static void Main (string[] args) {
Thread mythread = new Mythread ();
Mythread.start ();
}
The results of the implementation are as follows:
The result shows that the construction method of the Mythread class is called by the main thread, and the Run method is called by a thread named Thread-0, and the Run method is invoked automatically.
The code should read as follows:
public class Run {public
static void Main (string[] args) {
Thread mythread = new Mythread ();
Mythread.start ();
Mythread.run ();
}
To test a more complex, sample code is as follows:
public class Countoperate extends thread{public
countoperate () {
System.out.println ("----countoperate Begin----");
System.out.println ("Countoperate thread.currentthread (). GetName:" +thread.currentthread (). GetName ());
System.out.println ("Countoperate this.getname:" +this.getname ());
SYSTEM.OUT.PRINTLN ("----countoperate end----");
}
@Override public
Void Run () {
System.out.println ("----Run begin----");
System.out.println ("Run Thread.CurrentThread (). GetName:" +thread.currentthread (). GetName ());
System.out.println ("Run This.getname:" +this.getname ());
SYSTEM.OUT.PRINTLN ("----Run end----");
}
public class Run {public
static void Main (string[] args) {
countoperate c = new Countoperate ();
thread T1 = new Thread (c, "A");
SYSTEM.OUT.PRINTLN (t1);
T1.start ();
}
The results of the operation are as follows:
GetName () and Thread.CurrentThread (). GetName () return a different value, you can modify the code as follows:
public class Countoperate extends thread{public
countoperate (String name) {
super (name);
SYSTEM.OUT.PRINTLN ("----countoperate begin----");
System.out.println ("Countoperate thread.currentthread (). GetName:" +thread.currentthread (). GetName ());
System.out.println ("Countoperate this.getname:" +this.getname ());
SYSTEM.OUT.PRINTLN ("----countoperate end----");
}
public class Runcountoperate {public
static void Main (string[] args) {
countoperate countoperate = new Countopera Te ("M");
Countoperate.setname ("N");
thread T1 = new Thread (countoperate);
T1.setname ("A");
T1.start ();
}
The results of the implementation are as follows:
This result shows that the This.getname () method refers to the thread name of the current object, while the Thread.currentThread.getName () method represents the name of the running thread. isAlive () method:
The function of the IsAlive () method is to determine whether the current thread is active.
Create the sample code as follows:
public class Mythread extends thread{
@Override public
void Run () {
System.out.println ("---run:" + This.isalive () + "---");
}
public class Run {public
static void Main (string[] args) {
mythread m = new Mythread ();
System.out.println ("begin=" +m.isalive ());
M.start ();
System.out.println ("end=" +m.isalive ());
}
The results of the program operation are as follows:
The purpose of the method IsAlive () is to test whether the thread is active. What is the active state. The active state is that the thread has started and has not been terminated. Thread is in a state that is running or ready to start, and the thread is considered to be alive.
You need to explain the following code:
System.out.println ("end=" +m.isalive ());
Although the above example prints the result is true, this value is indeterminate. Print true because the mythread thread has not finished executing, so the output is true. If the code changes to the following:
public class Run {public
static void Main (string[] args) throws interruptedexception {
mythread m = new Mythread ( );
System.out.println ("begin=" +m.isalive ());
M.start ();
Thread rest One second
thread.sleep (1000);
System.out.println ("end=" +m.isalive ());
}
Execution results:
The above code output is false because the mythread thread has finished executing in 1 seconds.
In addition, when you use the IsAlive () method, the result of the run differs from the preceding if the thread object is passed to the thread object in the form of a construction parameter to start (). The difference is due to the difference between thread.currentthread () and this. The following code tests:
public class Countoperate extends thread{public countoperate (String name) {super (name);
SYSTEM.OUT.PRINTLN ("----countoperate begin----");
System.out.println ("Countoperate thread.currentthread (). GetName:" +thread.currentthread (). GetName ());
System.out.println ("Countoperate thread.currentthread (). IsAlive:" +thread.currentthread (). isAlive ());
System.out.println ("Countoperate this.getname:" +this.getname ());
System.out.println ("Countoperate this.getname:" +this.isalive ());
SYSTEM.OUT.PRINTLN ("----countoperate end----");
@Override public void Run () {System.out.println ("----Run begin----");
System.out.println ("Run Thread.CurrentThread (). GetName:" +thread.currentthread (). GetName ());
System.out.println ("Run Thread.CurrentThread (). IsAlive:" +thread.currentthread (). isAlive ());
System.out.println ("Run This.getname:" +this.getname ());
System.out.println ("Run This.isalive:" +this.isalive ());
SYSTEM.OUT.PRINTLN ("----Run end----"); } public class Runcountoperate {pubLic static void Main (string[] args) {countoperate countoperate = new Countoperate ("M");
Countoperate.setname ("N");
thread T1 = new Thread (countoperate);
SYSTEM.OUT.PRINTLN ("Main begin T1 Isalive=" +t1.isalive ());
T1.setname ("A");
T1.start ();
System.out.println ("Main end T1 isalive=" +t1.isalive ());
}
}
The results of the implementation are as follows:
Sleep () method
Method Sleep () is used to hibernate (suspend execution) the currently executing thread within the specified number of milliseconds. This "executing thread" refers to the thread returned by This.currentthread ().
With an example description, the following:
public class MyThread1 extends thread{
@Override public
void Run () {
System.out.println ("Run Threadname=" + This.currentthread (). GetName () + "Begin");
try {
thread.sleep;
} catch (Interruptedexception e) {
e.printstacktrace ();
}
System.out.println ("Run Threadname=" +this.currentthread (). GetName () + "End");
}
public class Run1 {public
static void Main (string[] args) {
MyThread1 t1 = new MyThread1 ();
System.out.println ("begin=" +system.currenttimemillis ());
T1.run ();
System.out.println ("end=" +system.currenttimemillis ());
}
The results of the run code are as follows:
Continue to modify the code as follows:
public class MyThread2 extends thread{
@Override public
void Run () {
System.out.println ("Run Threadname=" + This.currentthread (). GetName () + "begin=" +system.currenttimemillis ());
try {
thread.sleep;
} catch (Interruptedexception e) {
e.printstacktrace ();
}
System.out.println ("Run Threadname=" +this.currentthread (). GetName () + "end=" +system.currenttimemillis ());
}
Public
class Run2 {public
static void Main (string[] args) {
MyThread2 t2 = new MyThread2 ();
System.out.println ("begin=" +system.currenttimemillis ());
T2.start ();
System.out.println ("end=" +system.currenttimemillis ());
}
The results of the operation are as follows:
Because the main thread and the THREAD2 thread are executed asynchronously, the first printed information begins and end. The MyThread2 later executes and prints the run begin and run end information in the last two lines. getId () method
The purpose of the GetId () method is to obtain a unique identity for the thread. 、
Create the sample code as follows:
public class Run1 {public
static void Main (string[] args) {
thread thread = Thread.CurrentThread ();
System.out.println (Thread.getname () + "" +thread.getid ());
}
}
The results of the program operation are as follows: