Wait, notify, notifyallwait, sleep, yield difference?
Sleep frees up the CPU but does not release the lock.
public class Test {public static void main (string[] args) {Object Obj=new object (); Threadone one=new threadone (obj); Threadtwo two=new threadtwo (obj); One.start (); Two.start ();}} Class Threadone extends Thread{private object obj;public threadone (Object obj) {this.obj=obj;} @Overridepublic void Run () {synchronized (obj) {System.out.println (Thread.CurrentThread (). GetName ()); for (int i =0;i<5;i++) {System.out.println ("" +i); try {thread.sleep (1000); } catch (Interruptedexception e) {e.printstacktrace (); }}}}}class Threadtwo extends Thread{private object obj;public threadtwo (Object obj) {this.obj=obj;} @Overridepublic void Run () {synchronized (obj) {System.out.println (Thread.CurrentThread (). GetName ()); for (int i =0;i<5;i++) {System.out.println ("" +i); try {thread.sleep (1000); } catch (IntErruptedexception e) {e.printstacktrace (); } } }}}
Wait can only be called in a synchronous method or method block ( that is, the lock that needs to get the object ), and wait yields CPU usage and object locks
When the thread is in the wait () state, the interrupt () method of the calling thread object presents a Interruptedexception exception.
Beginner's Pit
public class Mistake {public static void main(String[] args) { Object object=new Object(); MyThreadThree threadThree=new MyThreadThree(object); threadThree.start();}}class MyThreadThree extends Thread{private Object object;public MyThreadThree(Object object){ this.object=object;}@Overridepublic void run(){ synchronized (object){ for (int i=1;i<5;i++){ try { wait();//坑点 } catch (InterruptedException e) { e.printStackTrace(); } } }}}
Pit point: Wait () requires a call to the lock object. Wait () The wait () of the above code is the wait for the thread object, so throw illegalmonitorstateexception, It is a subclass of RuntimeException that does not require try-catch to catch exceptions.
object.wait();//将wait()改为object.wait()就正确了
Notify, Notifyall also need to be called in a synchronous method or method block ( that is, a lock that needs to get an object ) after calling notify or Notifyall and not immediately releasing the lock requires that the program be executed after exiting the synchronized code block.
The difference between notify and Notifyall is that notify wakes up a wait thread to make its state runnable (operational), and Notifyall is the thread that wakes all wait
public class Test {public static void main (string[] args) {Service service=new service (); Threadone one=new threadone (service); Threadtwo two=new threadtwo (service); One.start (); Two.start ();}} Class Service{private Volatile Boolean flag =true;public Boolean Getflag () {return flag;} public void Setflag (Boolean flag) {This.flag=flag;}} Class Threadone extends Thread{private service service;public threadone (service service) {This.service=service;} @Overridepublic void Run () {synchronized (service) {while (true) {if (Service.getflag () ==true) { try {System.out.println ("blocked one"); Service.wait (); } catch (Interruptedexception e) {e.printstacktrace (); }}else{System.out.println (Thread.CurrentThread (). GetName () + "one"); Service.setflag (TRUE); Service.notifyall (); }}}}}class Threadtwo extends Thread{private service service;public threadtwo (service service) {This.service=service;} @Overridepublic void Run () {synchronized (service) {while (true) {if (Service.getflag () ==false) { try {System.out.println ("blocked by"); Service.wait (); } catch (Interruptedexception e) {e.printstacktrace (); }}else{System.out.println (Thread.CurrentThread (). GetName () + "both"); Service.setflag (FALSE); Service.notifyall (); } } }}}
Yield yields CPU usage, but does not release object locks.
public class TestYield {public static void main(String[] args) { Object object=new Object(); YieldThread yieldThread=new YieldThread(object); yieldThread.start(); YieldThread yieldThreadTwo=new YieldThread(object); yieldThreadTwo.start();}}class YieldThread extends Thread{private Object object;public YieldThread(Object object){ this.object=object;}@Overridepublic void run(){ synchronized (object) { for (int i = 1; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " " + i); Thread.yield(); } }}}
public class TestYield {public static void main(String[] args) { YieldThread yieldThread = new YieldThread(); yieldThread.start(); YieldThread yieldThreadTwo = new YieldThread(); yieldThreadTwo.start();}}class YieldThread extends Thread {@Overridepublic void run() { for (int i = 1; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " " + i); Thread.yield(); }}}
Summarize
- Wait to let the CPU use the yield object lock
- Sleep, yield let the CPU use but do not give up the object lock
- Wait, notify, Notifyall can only be called in a synchronous method or method block ( that is, the lock that needs to get the object ) or it will be thrown illegalmonitorstateexception
Notify, Notifyall
First look at a producer of multiple consumers
public class Testcp {public static void main (string[] args) {list<string> storehouse = new arraylist<> (0); Consumer Consumer = new Consumer (storehouse); Producer Producer = new Producer (storehouse); for (int i = 0; i < 1; i++) {new Producerthread (producer). Start (); } for (int i = 0; i <; i++) {New Consumerthread (consumer). Start (); }}}class Consumer {//Factory library Private list<string> storehouse;public Consumer (list<string> storehouse) {This.sto rehouse = storehouse;} Consumption public void consume () {synchronized (storehouse) {while (storehouse.size () = = 0) {try { System.out.println ("No cake ..."); Storehouse.wait (); } catch (Interruptedexception e) {e.printstacktrace (); }}//Consumption of the first storehouse.remove (0); Storehouse.notify (); }}}class Consumerthread extends Thread {private Consumer consumer;public Consumerthread(Consumer Consumer) {this.consumer = consumer;} @Overridepublic void Run () {while (true) {consumer.consume (); }}}class Producer {//Factory library Private list<string> storehouse;public Producer (list<string> storehouse) {This.sto rehouse = storehouse;} Production public void produce () {synchronized (storehouse) {//When the cake data in the factory library is 10 stop production while (storehouse.size () = = {try {System.out.println ("10 Pieces of cake"); Storehouse.wait (); } catch (Interruptedexception e) {e.printstacktrace (); }}//Production storehouse.add ("cake"); Storehouse.notify (); }}}class Producerthread extends Thread {private Producer producer;public producerthread (Producer Producer) {This.produ cer = producer;} @Overridepublic void Run () {while (true) {producer.produce (); }}}
Clogged up ... Why???
- Because there are only 10 of 20 consumer cakes, such as when there are 15 consumers waiting
- When the number of cakes produced by a producer reaches 10, wait
- There are 5 consumer consumer notify Wake up is waiting for consumers, when the consumption of 10 cakes after notify or consumers so, all consumers into the wait state and the producer is also wait state so blocked.
The notify will be executed correctly after it has been changed to Notifyall. 、
storeHouse.notifyAll();
Recommended use of Notifyall
Inter-thread communication: Pipelines
One line Cheng the data to the output pipeline, and the other thread reads the data from the input pipeline.
BYTE stream
Import Java.io.ioexception;import Java.io.pipedinputstream;import Java.io.pipedoutputstream;public class Run {public static void Main (string[] args) {try {writedata writedata = new WriteData (); ReadData ReadData = new ReadData (); PipedInputStream InputStream = new PipedInputStream (); PipedOutputStream outputstream = new PipedOutputStream (); Inputstream.connect (OutputStream) outputstream.connect (InputStream); Threadread threadread = new Threadread (readdata,inputstream); Threadread.start (); Thread.Sleep (2000); Threadwrite threadwrite=new Threadwrite (Writedata,outputstream); Threadwrite.start (); } catch (IOException e) {e.printstacktrace (); } catch (Interruptedexception e) {e.printstacktrace (); }}}class writedata {public void Writemethod (PipedOutputStream out) {try {System.out.println ("write:"); for (int i = 0; i < i++) {String Outdata = "" + (i + 1); Out.write (Outdata.getbytes ()); System.out.print (Outdata); } System.out.println (); Out.close (); } catch (IOException e) {e.printstacktrace (); }}}class Threadwrite extends Thread {private WriteData write;private pipedoutputstream out;public threadwrite (WriteData Write, PipedOutputStream out) {this.write = write; This.out = out;} @Overridepublic void Run () {Write.writemethod (out);}} Class ReadData {public void Readmethod (PipedInputStream input) {try {System.out.println ("read:"); byte[] ByteArray = new BYTE[20]; int readlength = Input.read (ByteArray); while (readlength! =-1) {String newdata = new String (byteArray, 0, readlength); System.out.print (NewData); Readlength = Input.read (ByteArray); } System.out.println (); Input.close (); } catch (IOException e) {e.printstacktrace (); }}}class Threadread extends Thread {PRIvate readdata read;private pipedinputstream input;public threadread (readdata read, PipedInputStream input) {This.read = Read; This.input = input;} @Overridepublic void Run () {read.readmethod (input);}}
Inputstream.connect (OutputStream) or Outputstream.connect (InputStream) causes a communication link between two streams
Character Stream
Import java.io.*;p Ublic class Run {public static void main (string[] args) {try {writedata writedata = new writ EData (); ReadData ReadData = new ReadData (); Pipedreader reader = new Pipedreader (); PipedWriter writer = new PipedWriter (); Writer.connect (reader); Reader.connect (writer); Threadread threadread = new Threadread (Readdata,reader); Threadread.start (); Thread.Sleep (2000); Threadwrite threadwrite=new Threadwrite (writedata,writer); Threadwrite.start (); } catch (IOException e) {e.printstacktrace (); } catch (Interruptedexception e) {e.printstacktrace (); }}}class writedata {public void Writemethod (PipedWriter out) {try {System.out.println ("write:"); for (int i = 0; i <; i++) {String Outdata = "" + (i + 1); Out.write (Outdata); System.out.print (Outdata); } System.out.println (); Out.close (); } CATCH (IOException e) {e.printstacktrace (); }}}class Threadwrite extends Thread {private WriteData write;private pipedwriter out;public threadwrite (WriteData write, PipedWriter out) {this.write = write; This.out = out;} @Overridepublic void Run () {Write.writemethod (out);}} Class ReadData {public void Readmethod (Pipedreader input) {try {System.out.println ("read:"); char[] ByteArray = new CHAR[20]; int readlength = Input.read (ByteArray); while (readlength! =-1) {String newdata = new String (byteArray, 0, readlength); System.out.print (NewData); Readlength = Input.read (ByteArray); } System.out.println (); Input.close (); } catch (IOException e) {e.printstacktrace (); }}}class Threadread extends Thread {private readdata read;private pipedreader input;public threadread (ReadData read, Pipe Dreader input) {this.read = read; This.input = input;} @Overridepublic void Run () { Read.readmethod (input);}}
Join
If you now have two threads, one thread wants to wait until another thread finishes running and then you can use join.
public class TestJoin {public static void main(String[] args) { MyThreadJoin join=new MyThreadJoin(); join.start(); try { join.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" 我在等他结束后运行!!!");}}class MyThreadJoin extends Thread{@Overridepublic void run(){ System.out.println("sleep.........."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }}}
The join source uses the Wait () method to implement ———— and says join yields CPU usage and object locks
/** * Waits at the most {@code Millis} milliseconds for this thread to * die. A timeout of {@code 0} means to wait forever. * * <p> This implementation uses a loop of {@code this.wait} calls * conditioned on {@code this.isalive}. As a thread terminates the * {@code This.notifyall} method is invoked. IT is recommended this * applications not use {@code wait}, {@code notify}, or * {@code notifyall} on {@code Thread} Insta NCEs. * * @param Millis * The time to wait in milliseconds * * @throws illegalargumentexception * If the Valu E of {@code Millis} is negative * * @throws interruptedexception * If any thread have interrupted the current THR ead. The * <i>interrupted status</i> of the current thread was * cleared when this exception is th Rown. */public final synchronized void join (long Millis) throws Interruptedexception {Long base = System.currenttimemillis (); Long now = 0; if (Millis < 0) {throw new IllegalarguMentexception ("Timeout value is negative"); } if (Millis = = 0) {while (isAlive ()) {wait (0); }} else {while (isAlive ()) {long delay = Millis-now; if (delay <= 0) {break; } wait (delay); now = System.currenttimemillis ()-base; } }}
Join yields object lock
public class Testjoin {public static void main (string[] args) {threadb b=new threadb (); Threada a=new Threada (b); A.start (); try {thread.sleep (1000); } catch (Interruptedexception e) {e.printstacktrace (); } THREADC c=new THREADC (b); C.start ();}} Class Threada extends Thread{private threadb threadb;public Threada (threadb threadb) {this.threadb=threadb;} @Overridepublic void Run () {try{synchronized (threadb) {Threadb.start (); Thread.Sleep (6000); }}catch (Interruptedexception e) {e.printstacktrace (); }}}class threadb extends thread{@Overridepublic void run () {try {System.out.println ("threadb Run begin Time" + System.currenttimemillis ()); Thread.Sleep (5000); System.out.println ("Threadb Run End Time" +system.currenttimemillis ()); }catch (interruptedexception e) {e.printstacktrace (); }}public synchronized void bservice () {System.out.println ("bservice Time" +System.currenttimemillis ());}} Class THREADC extends Thread{private threadb threadb;public threadc (threadb threadb) {this.threadb=threadb;} @Overridepublic void Run () {Threadb.bservice ();}}
Change the Run () method of Threada to
threadB.join();//Thread.sleep(6000);
Java multithreaded Programming Core technology
If there is anything wrong welcome to point out, thanks thank you! Learn to understand the shallow hope.
Threading Basics (iii)