1: Description of processes and threads:
Processes: Each process has its own code and data space (process context), and switching between processes can be costly, with 1 to n threads per process.(Process is the smallest unit of resource allocation)
Threads: The same type of thread shares code and data space, each thread has its own run stack and program counter (PC), and thread switching costs are low.(Threads are the smallest unit of cpu scheduling)
Two: Common ways to achieve multithreading:
1. Inherit the Thread class
2. Implement Runnable Interface
Three: For direct inheritance Thread
See examples:
public class Zy extends Thread{ private String name; public Zy(){} public Zy(String name){ this.name = name; } public void run(){ for (int i=0;i<5;i++){ System.out.println(name+"implement "+i+"second"); } }
public class Test { public static void main(String[] args) { Zy z1 = new Zy("z1"); Zy z2 = new Zy("z2"); z1.run(); //You cannot call it directly here test()Method z2.run(); //Here the run method hand is to override the run method of Thread before calling it to start () } }
Implement effect:
z1 executed 0 times z1 executed once z1 executed twice z1 executed three times z1 executed four times z2 executed 0 times z2 executes once z2 executed twice z2 executed three times z2 executed four times
This method is executed in the wrong order and the start() method should be called
public static void main(String[] args) { Zy z1 = new Zy("z1"); Zy z2 = new Zy("z2"); z1.start(); z2.start(); }
Note: The effect can only be achieved if the run() method start() method in Thread is overridden.
Achieving results
z2 executed 0 times z1 executed 0 times z2 executes once z1 executed once z2 executed twice z1 executed twice z2 executed three times z1 executed three times z2 executed four times z1 executed four times
Since CPU resources are required, the results are basically different for each run.
As to why the run() method cannot be called directly, it should be that the running of threads requires support from the local operating system.
start0 () is called here.And this method uses the native keyword, which means a function that calls the local operating system.This is because multithreaded implementations require support from the local operating system.
By implementing the Runnable interface
public class Zy implements Runnable{ private String name; public Zy(){} public Zy(String name){ this.name = name; } public void run(){ for (int i=0;i<5;i++){ System.out.println(name+"implement "+i+"second"); } } }
public static void main(String[] args) { Zy z1 = new Zy("z1"); Thread t1 = new Thread(z1); Zy z2 = new Zy("z2"); Thread t2 = new Thread(z2); t1.start(); t2.start(); }
//Execution results
For the first time:
z1 executed 0 times z1 executed once z2 executed 0 times z2 executes once z2 executed twice z2 executed three times z2 executed four times z1 executed twice z1 executed three times z1 executed four times
The second time:
z1 executed 0 times
z1 executed once
z1 executed twice
z1 executed three times
z1 executed four times
z2 executed 0 times
z2 executes once
z2 executed twice
z2 executed three times
z2 executed four times
//Each execution results are roughly different, if roughly the same, your operating system may be more stable, Huh-huh
About inheriting Thread or implementing the Runnable interface?
View Source Discovery
public class Thread implements Runnable { /* Make sure registerNatives is the first thing <clinit> does. */ private static native void registerNatives(); static { registerNatives(); }
Thread also implements the Runnable interface, and both Thread and Runnable implement the run method, which is actually the proxy mode.I am not sure about the proxy mode, but here: http://www.cnblogs.com/rollenholt/archive/2011/08/18/2144847.html
The difference between Thread and Runnable:
1. If a class inherits Thread, it is not suitable for resource sharing.But if you implement the Runable interface, resource sharing is easy.
This implementation inherits Thread
public class Zy extends Thread{private int count=5;
public void run(){
for (int i = 0; i < 6; i++) {
if (count > 0) {
System.out.println("Number= " + count--);
}
}
}
public static void main(String[] args) {
Zy z1 = new Zy();
Thread t1 = new Thread(z1);
Zy z2 = new Zy();
Thread t2 = new Thread(z2);
t1.start();
t2.start();
}}
Execution effect
Quantity = 5 Quantity = 4 Quantity = 3 Quantity = 2 Quantity = 1 Quantity = 5 Quantity = 4 Quantity = 3 Quantity = 2 Quantity = 1
This description resource is not shared, change to runnable interface
public class Zy implements Runnable{ private int count=5; public void run(){ for (int i = 0; i < 6; i++) { if (count > 0) { System.out.println("Number= " + count--); } } } public static void main(String[] args) { Zy zy = new Zy(); new Thread(zy,"1 Number window").start(); new Thread(zy, "2 Number window").start(); new Thread(zy, "3 Number window").start(); } }
(possible) effect
Quantity = 5 Quantity = 2 Quantity = 1 Quantity = 3 Quantity = 4
To summarize:
Implementing the Runnable interface has advantages over inheriting the Thread class:
1: For multiple threads of the same program code to process the same resource
2): can avoid single inheritance restrictions in java
3): Increase the robustness of the program, code can be shared by multiple threads, code and data independent.
Also, the main method is actually a thread.All threads in java start at the same time, and when and which executes first depends entirely on who gets the CPU's resources first.
In java, at least two threads are started per program run.One is the main thread and the other is the garbage collection thread.Because whenever a class is executed using a Java command, a JVM is actually started, and each jVM is actually a process started in the operating system.
Four: Determine if a thread is started
public void run() { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName()); } } public static void main(String[] args) { Zy zy = new Zy(); Thread demo = new Thread(zy); System.out.println("Before the thread starts--->" + demo.isAlive()); demo.start(); System.out.println("After the thread starts--->" + demo.isAlive()); }
- Execution results
Before the thread starts ---"false After the thread starts ---"true Thread-0 Thread-0 Thread-0
The main thread may also end before the child thread ends.Subthreads are unaffected and do not end with the end of the main thread.
Five: Thread's mandatory join:
public class Zy implements Runnable{ public void run() { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName()); } } public static void main(String[] args) { Zy zy = new Zy(); Thread demo = new Thread(zy,"thread"); demo.start(); for(int i=0;i<10;++i){ if(i>5){ try{ demo.join(); //Enforce demo }catch (Exception e) { e.printStackTrace(); } } System.out.println("main Thread Execution-->"+i); } } }
Execution results
main thread execution-->0 main thread execution-->1 main thread execution-->2 main thread execution-->3 main thread execution-->4 main thread execution-->5 thread Thread//is forced before the main thread has finished thread main thread execution-->6 main thread execution-->7 main thread execution-->8 main thread execution-->9
Six: Thread sleep:
public class Zy implements Runnable{ public void run() { for (int i = 0; i < 3; i++) { try { Thread.sleep(2000); //2000 2 seconds } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + i); } } public static void main(String[] args) { Zy zy = new Zy(); Thread demo = new Thread(zy, "thread"); demo.start(); } }
Execution results
Thread 0 Thread 1 Thread 2//Print one in less than two seconds
Seven, thread interrupt()
public class Zy implements Runnable{ public void run() { System.out.println("implement run Method"); try { Thread.sleep(10000); System.out.println("Thread Completes Sleep"); } catch (Exception e) { System.out.println("Hibernation interrupted"); return; //Return to the call of the program } System.out.println("Thread terminated normally"); } public static void main(String[] args) { Zy zy = new Zy(); Thread demo = new Thread(zy, "thread"); demo.start(); try{ Thread.sleep(2000); }catch (Exception e) { e.printStackTrace(); } demo.interrupt(); //2s Post-interrupt thread }
}
Execution results
Execute run method --- Two seconds after interval Hibernation interrupted
In a Java program, as long as one thread in the foreground is running, the entire Java program process will not disappear, so you can set a background thread at this time, so that even if the java process disappears, the background thread can continue to run.Main thread interrupt does not interrupt child threads
public class Zy implements Runnable{ public void run() { while (true) { System.out.println(Thread.currentThread().getName() + "Running"); } } public static void main(String[] args) { Zy zy = new Zy(); Thread demo = new Thread(zy, "thread"); demo.setDaemon(true); demo.start(); } }
Eight: Thread Priority
* View Thread Source Discovery
/** * The minimum priority that a thread can have. //Lowest */ public final static int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public final static int MAX_PRIORITY = 10;//The smaller the MIN_PRIORITY value, the lower the priority
public class Zy implements Runnable{ public void run() { for(int i=0;i<5;++i){ System.out.println(Thread.currentThread().getName()+"Function"+i); } } public static void main(String[] args) { Thread h1=new Thread(new Zy(),"A"); Thread h2=new Thread(new Zy(),"B"); Thread h3=new Thread(new Zy(),"C"); h1.setPriority(8); h2.setPriority(2); h3.setPriority(6); h1.start(); h2.start(); h3.start(); } }
Printing effect
A Run 0 A Run 1 A Run 2 A Run 3 A Run 4 C Run 0 C Run 1 C Run 2 C Run 3 C Run 4 B Run 0 B Run 1 B Run 2 B Run 3 B Run 4
However, please do not mistake the reader for executing the higher priority.Who executes first or depends on who goes first to the CPU's resources, don't know if it is
The higher the value of NORM_PRIORITY, who gets the cpu resource first. I executed n times with the same result?
In addition, the priority of the main thread is 5.
Nine: Thread's gift.
In threaded operations, you can also use the yield() method to temporarily delegate operations from one thread to another.
public class Zy implements Runnable{ public void run() { for(int i=0;i<5;++i) { System.out.println(Thread.currentThread().getName() + "Function" + i); if (i == 3) { System.out.println("Thread's gift"); Thread.currentThread().yield(); } } } public static void main(String[] args) { Thread h1=new Thread(new Zy(),"A"); Thread h2=new Thread(new Zy(),"B"); h1.start(); h2.start(); } }
Execution effect
A Run 0 A Run 1 A Run 2 A Run 3 Thread's gift B Run 0 B Run 1 B Run 2 B Run 3 Thread's gift A Run 4 B Run 4
10: Synchronization and deadlock.
public class Zy implements Runnable{ private int count=5; public void run() { for(int i=0;i<10;++i){ if(count>0){ try{ Thread.sleep(1000); //Take a second off }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(count--); } } } public static void main(String[] args) { Zy zy = new Zy(); Thread h1=new Thread(zy); Thread h2=new Thread(zy); Thread h3=new Thread(zy); h1.start(); h2.start(); h3.start(); } }
Execution effect
5 3 4 2 2 2 1 0 -1
There should be a conflict between threads.
If you want to solve this problem, you need to use synchronization.Synchronization means that only one thread runs in a uniform period of time.
Other threads must wait until the end of this thread to continue execution.
[Synchronize code blocks]:
Grammar Format:
synchronized {
//Code requiring synchronization
}
public class Zy implements Runnable{ private int count=5; public void run() { for(int i=0;i<10;++i){ synchronized (this) { if (count > 0) { try { Thread.sleep(1000); //Take a second off } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count--); } } } } public static void main(String[] args) { Zy zy = new Zy(); Thread h1=new Thread(zy); Thread h2=new Thread(zy); Thread h3=new Thread(zy); h1.start(); h2.start(); h3.start(); } }
results of enforcement
5 4 3 2 1 //Output one in no seconds
[Synchronization method]
Synchronization can also be used.
Syntax format is synchronized method return type method name (parameter list){
// Other Code
}
public class Zy implements Runnable{ private int count=5; public void run() { for (int i = 0; i < 10; ++i) { sale(); } } public synchronized void sale() { if (count > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count--); } } public static void main(String[] args) { Zy zy = new Zy(); Thread h1=new Thread(zy); Thread h2=new Thread(zy); Thread h3=new Thread(zy); h1.start(); h2.start(); h3.start(); } }
//The output is the same. Don't believe you can try it
deadlock
Synchronization is required when multiple threads share a resource, but too much synchronization can lead to deadlocks.
[Producer and consumer issues]
/* *Public Information Class */ public class Info { public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } private String name = "Rollen"; private int age = 20; } /** *Consumer class */ public class Consumer implements Runnable { private Info info=null; public Consumer(Info info){ this.info=info; } public void run(){ for(int i=0;i<25;++i){ try{ Thread.sleep(100); }catch (Exception e) { e.printStackTrace(); } System.out.println(this.info.getName()+"<---->"+this.info.getAge()); } } } /** *Production Class */ public class Producer implements Runnable { private Info info=null; Producer(Info info){ this.info=info; } public void run(){ boolean flag=false; for(int i=0;i<25;++i){ if(flag){ this.info.setName("Rollen"); try{ Thread.sleep(100); }catch (Exception e) { e.printStackTrace(); } this.info.setAge(20); flag=false; }else{ this.info.setName("chunGe"); try{ Thread.sleep(100); }catch (Exception e) { e.printStackTrace(); } this.info.setAge(100); flag=true; } } } }
Test Class
public static void main(String[] args) { Info info = new Info(); Producer pro = new Producer(info); Consumer con = new Consumer(info); new Thread(pro).start(); new Thread(con).start(); }
test result
Rollen<---->100 chunGe<---->20 chunGe<---->100 Rollen<---->100 chunGe<---->20 chunGe<---->20 Rollen<---->100 Rollen<---->100 Rollen<---->100 chunGe<---->20 chunGe<---->100 chunGe<---->20 chunGe<---->20 chunGe<---->20 chunGe<---->100 Rollen<---->20 chunGe<---->100 Rollen<---->20 chunGe<---->100 chunGe<---->20 Rollen<---->100 chunGe<---->20 Rollen<---->100 Rollen<---->20 chunGe<---->20 //Name does not correspond to age
So how can I solve it?
1) Join Synchronization
2) Join Waiting and Waking
First, join synchronization
class Info { public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public synchronized void set(String name, int age){ this.name=name; try{ Thread.sleep(100); }catch (Exception e) { e.printStackTrace(); } this.age=age; } public synchronized void get(){ try{ Thread.sleep(100); }catch (Exception e) { e.printStackTrace(); } System.out.println(this.getName()+"<===>"+this.getAge()); } private String name = "Rollen"; private int age = 20; } /** * Producer * */ class Producer implements Runnable { private Info info = null; Producer(Info info) { this.info = info; } public void run() { boolean flag = false; for (int i = 0; i < 25; ++i) { if (flag) { this.info.set("Rollen", 20); flag = false; } else { this.info.set("ChunGe", 100); flag = true; } } } } /** * Consumer class * */ class Consumer implements Runnable { private Info info = null; public Consumer(Info info) { this.info = info; } public void run() { for (int i = 0; i < 25; ++i) { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } this.info.get(); } } } /** * Test Class * */ class hello { public static void main(String[] args) { Info info = new Info(); Producer pro = new Producer(info); Consumer con = new Consumer(info); new Thread(pro).start(); new Thread(con).start(); } }
Achieving results
Rollen<===>20 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 ChunGe<===>100 ChunGe<===>100 ChunGe<===>100 ChunGe<===>100 ChunGe<===>100 ChunGe<===>100 ChunGe<===>100 ChunGe<===>100
Name and age correspond, but there is a problem with duplicate coverage
If you want to solve this problem, you need to use the Object class to help,
And we can use the wait and wake operations.
To do this, we only need to modify Info class hunger, add markers to it, and complete the wait and wake-up operations by judging the markers, as shown in the code below
public synchronized void set(String name, int age){ if(!flag){ try{ super.wait(); }catch (Exception e) { e.printStackTrace(); } } this.name=name; try{ Thread.sleep(100); }catch (Exception e) { e.printStackTrace(); } this.age=age; flag=false; super.notify(); } public synchronized void get(){ if(flag){ try{ super.wait(); }catch (Exception e) { e.printStackTrace(); } } try{ Thread.sleep(100); }catch (Exception e) { e.printStackTrace(); } System.out.println(this.getName()+"<===>"+this.getAge()); flag=true; super.notify(); } private String name = "Rollen"; private int age = 20; private boolean flag=false;
Result
Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20 ChunGe<===>100 Rollen<===>20
Problem solving
Original address: http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html