多线程(二)

来源:互联网 发布:java 图片尺寸 编辑:程序博客网 时间:2024/06/10 12:23

六、多线程的应用

 

1、线程间的通讯

/* 线程间通讯: 其实就是多个纯种在操作同一个资源,但是操作的动作不同。*/package day2;class Res1{String name;String sex;boolean flag = false;};class Input1 implements Runnable{private Res1 r;Input1(Res1 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 Output1 implements Runnable{private Res1 r;Output1(Res1 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();}}}};public class  InputOutputDemo{public static void main(String[] args) {Res1 r = new Res1();Input1 in = new Input1(r);Output1 out = new Output1(r);Thread t1 = new Thread(in);Thread t2 = new Thread(out);t1.start();t2.start();}}

2、JDK1.5中提供了多线程升级解决方案。



/*JDK1.5中提供了多线程升级解决方案。 * 将同步synchronized替换成显示的Lock操作。 * 将Object中的wait,natify,natifyAll,替换了Condition对象。 * 该对象可以Lock锁进行获取。 *  * 该示例中,实现了本方只唤醒对方操作。 * */import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class Res{String name;String sex;boolean flag = false;private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();public  void set(String name,String sex){lock.lock();while(flag)try {condition.await();} catch (InterruptedException e) {e.printStackTrace();}this.sex = sex;this.name = name;flag = true;condition.signal();lock.unlock();}public void get(){lock.lock();while(!flag)try {condition.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(name+"........"+sex);flag = false;    condition.signal();        lock.unlock();}};class Input implements Runnable{private Res r;Input(Res r){this.r = r;}public void run(){int x = 0;while(true){if(x==0)r.set("mike","man");elser.set("丽丽","美女");x = (x+1)%2;}}};class Output implements Runnable{private Res r;Output(Res r){this.r = r;}public void run(){while(true){r.get();}}};public class  InputOutputDemo2{public static void main(String[] args) {Res r = new Res();new Thread(new Input(r)).start();new Thread(new Output(r)).start();}}

3、(1)如何停止线程?(2)冻结:changeFlag();(3)解除冻结:interrupt();(4)守护(后台线程)线程:setDaemon


/* * 如何停止线程? * 只有一种,run方法结束。 * 开启多线程运行,运行代码通常是循环结构。 *  * 只要控制信循环,就可以让run方法结束,也就是纯种结束。  *  * 冻结:changeFlag(); * 特殊情况:如下例子没了interrupt()和对应在异常中处理 * 当线程处于了冻结状态。 * 就不会讲到到标记,那么线程就不会结束。 *  *  * 解除冻结:interrupt();会产生异常 * 当没有指定的方式让冻结的线程恢复到运行状态时,这里需要对冻结进行清除。 * 强制让线程恢复到运行状态来,这样就可以操作标记让线程结束。 *  * 守护(后台线程)线程:setDaemon * 开启后和主线程是同一级别,但它却依赖于主线程,所以不用去关闭它,只要主线程结束了它就自动结束。 *    如下例子不用去关闭标记为setDaemon的线程,主线程结束了,它也活不成了。 *  * */class StopThread implements Runnable{private boolean flag = true;public synchronized 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;}}public class SropThreadDemo {public static void main(String[] args){StopThread st = new StopThread();Thread t1 = new Thread(st);Thread t2 = new Thread(st);t1.setDaemon(true);t2.setDaemon(true);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()+"...."+num);}System.out.println("....over");}}

4、等待线程:join();

/* * 等待线程:Join(); 会产生异常 *    当A线程执行到了B线程的join()方法时,A就会等待,等 B线程执行完,Aft会执行。 *     *    join可以用来临时加入线程执行。 *     *    下例子中把join()放到t2线程后面,t2是不会受到影响,因为join()只作用当前线程。 * */class Demo implements Runnable{public void run(){for(int x=0;x<70;x++)System.out.println(Thread.currentThread().getName()+"...."+x);}}public class JoinDemo {public static void main(String[] args) {Demo d = new Demo();Thread t1 = new Thread(d);Thread t2 = new Thread(d);t1.start();t2.start();try {t1.join();} catch (InterruptedException e) {e.printStackTrace();}Thread.currentThread().setName("主线程");for(int x=0;x<60;x++)System.out.println(Thread.currentThread().getName()+"...."+x);System.out.println("over");}}



0 0
原创粉丝点击