class Res { String name; String sex; boolean flag = false; } class Input implements Runnable { private Res r ; Object obj = new Object(); Input(Res r) { this.r= r; } public void run() { int x = 0; while(true) { synchronized(r) { if(r.flag) try{r.wait();}catch(Exception e){} if(x==0) { r.name= "mike"; r.sex = "man"; } else { r.name= "--------------"; r.sex= "-------------"; } x = (x+1)%2; r.flag= true; r.notify(); } } } } class Output implements Runnable { private Res r; Output(Res r) { this.r = r; } public void run() { while(true) { synchronized(r) { if(!r.flag) try{r.wait();}catch(Exception e){} System.out.println(r.name+"----"+r.sex); r.flag= false; r.notify(); } } } } class InputOutputDemo { public static void main(String[] args) { Res r = new Res(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } }
多线程 线程间通信---等待唤醒机制。
wait;
notify();
notifyAll();
都使用在同步中,因为要对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只要同步才有锁、
为什么这些操作线程方法要定义在Object类中呢?
因为这些方法在操作同步中线程是,都必须要标识他们所操作线程只有的锁。
只有同一个锁上的被等待线程,可以被同一个锁上的notigy唤醒。
不可以对不同锁中的线程进行唤醒
也就是说,等待和唤醒必须是同一个锁。
而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object中
//线程运行时,内存会建立一个线程池,等待线程线程存在线程池,notify唤醒的的是线程池,唤醒第一个。
stop方法已经过时。
如何停止线程?
只有一种方法,run方法结束。
开启多线程运行,运行代码通常是循环结构。
只要控制循环就,就可以让run方法结束,也就是线程结束。
特殊情况:
当线程处于冻结状态,
就不会读取到标记,那么线程就不会结束。
当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除。
强制让线程恢复到运行状态来,这样就可以操作标记让线程结束。
Thread类提供该方法 interrupt();
class StopThread implements Runnable { private boolean flag = true; public void run() { while(flag) { try { wait(); } catch(InterruptedException e) { System.out.println(Thread.currentThread().getName()+"......Exception"); flag = false; } System.out.println(Thread.currentThread().getName()+"...run"); } } public void changeFlag() { flag = false; } } class StopThreadDemo { public static void main(String[] args) { StopThread st = new StopThread(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); t1.start(); t2.start(); int num = 0; while(true) { if(num++ == 60) { //st.changeFlag(); t1.interrupt(); t2.interrupt(); break; } System.out.println(Thread.currentThread().getName()); } } }
join的用法
当A线程执行到B线程的join方法时,A就会等待。等B线程都执行完,A才会执行。
join可以用来临时加入线程
class Demo implements Runnable { public void run() { for(int x = 0 ;x<70;x++) System.out.println(Thread.currentThread().toString()+ "----" + x); } } class JoinDemo { public static void main(String[] args) { Demo d = new Demo(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); t1.join();//测试 t2.start(); for(int x = 0;x<80;x++) System.out.println("main----"+x); System.out.println("over"); } }
ThreadTest 类
class ThreadTest { public static void main(String[] args) { new Thread() { public void run() { for(int x = 0; x<100;x++) System.out.println(Thread.currentThread().getName()+ "--------------" +x); } }.start(); for(int x =0 ;x<100;x++) System.out.println(Thread.currentThread().getName()+ "--------------" +x); Runnable r = new Runnable() { public void run() { for(int x = 0; x<100;x++) System.out.println(Thread.currentThread().getName()+ "--------------" +x); } }; new Thread(r).start(); } }