黑马程序员-------线程(下)
2014-03-12 16:54
337 查看
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
线程之间的通讯
生产者和消费者
JDK1.5多线程新特性
线程的停止
Thread其他方法
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
线程之间的通讯
package day12; /** * 线程之间的通讯 * @author hao * *多个线程操作同一个资源,但是操作的动作不同 * *等待唤醒机制 *根据现实生活,我们不仅需要 各个线程访问数据实现同步,还要让各个线程之间有相互的制约 * *例如:下面这个程序我们 需要的是存一个数据,取出一个数据 *其结果: * mick========boy 小红========女 mick========boy 小红========女 mick========boy 小红========女 mick========boy 小红========女 * * *wait(); notify(); notifyAll(); *它们对持有监视器的线程进行操作,所以要使用在同步当中 * *这些方法为什么要定义在Object类当中 *在操纵同步中的线程时,只有同一个锁上的被等待的线程,才可以被同一个锁上的notify唤醒 *不可以对不同锁中的线程进行唤醒。等待唤醒必须是同一个锁 *锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类当中国 * */ //资源 class Res { private String name; private String sex; boolean flag = false; public Res(String name, String sex) { super(); this.name = name; this.sex = sex; } public Res() { // TODO Auto-generated constructor stub } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } //输入资源 class Input implements Runnable { private Res r ; public Input(Res r) { super(); this.r = r; } public void run() { boolean flag = false; while(true) { synchronized(Res.class){ if(r.flag) try { Res.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } if(flag){ r.setName("mick"); r.setSex("boy"); flag =false; }else { r.setName("小红"); r.setSex("女"); flag = true; } r.flag = true; Res.class.notify(); } } } } //输出资源 class Output implements Runnable { private Res r ; public Output(Res r) { super(); this.r = r; } public void run() { while(true) synchronized(Res.class) { if(!r.flag) try { Res.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(r.getName()+"========"+r.getSex()); r.flag = false; Res.class.notify(); } } } public class InputOutputDemo { public static void main(String[] args) { Res r = new Res(); Thread t1 = new Thread(new Input(r)); Thread t2 = new Thread(new Output(r)); t1.start(); t2.start(); } }
生产者和消费者
package day12; /** * 线程通信 生产者消费者 * @author hao * *对于多个生产者和消费者 *为了让唤醒的线程再一次进行判断标记,我们要定义while判断标记 * *为什么要定义notifyAll *因为只用notify,容易出现只唤醒本方线程的情况,导致程序中的所有都等待 * *程序运行结果一部分: * Thread-1..生产者..大米编号:26642 Thread-2..消费者..大米编号:26642 Thread-0..生产者..大米编号:26643 Thread-3..消费者..大米编号:26643 Thread-1..生产者..大米编号:26644 Thread-2..消费者..大米编号:26644 Thread-0..生产者..大米编号:26645 Thread-3..消费者..大米编号:26645 Thread-1..生产者..大米编号:26646 Thread-2..消费者..大米编号:26646 Thread-0..生产者..大米编号:26647 */ class Resource { private String name; private int id = 1; boolean flag = false; //存资源 public synchronized void set(String name){ while(flag)//if 不能再判断 flag 程序会继续向下执行 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } this.name = name + "编号:"+id++; System.out.println(Thread.currentThread().getName()+"..生产者.."+this.name); flag = true; this.notifyAll(); } //输出资源 public synchronized void out(){ while(!flag) try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"..消费者.."+this.name); flag = false; this.notifyAll(); } } class Producer implements Runnable { Resource r; public Producer(Resource r) { this.r = r; } public void run() { while(true) r.set("大米"); } } class Consumer implements Runnable { Resource r; public Consumer(Resource r) { this.r = r; } public void run(){ while(true) r.out(); } } public class ProducerConsumerDemo { public static void main(String[] args) { Resource r = new Resource(); //简写方式 new Thread(new Producer(r)).start(); new Thread(new Producer(r)).start(); new Thread(new Consumer(r)).start(); new Thread(new Consumer(r)).start(); } }
JDK1.5多线程新特性
package day12; /** * JDK1.5 线程新特性 * @author hao * *JDK1.5 提供了多线程升级解决方案 *将现实Lock操作替换成 同步synchronized *将condition对象替换了Object中的wait,notify,notifyAll *给对象可以用Lock锁,进行获取 */ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Resource2 { private String name; private int id = 1; boolean flag = false; private Lock lock = new ReentrantLock();//创建锁 private Condition condition_pro = lock.newCondition();//关联锁 private Condition condition_con = lock.newCondition();
//存资源 public void set(String name) throws InterruptedException{ lock.lock(); try { while(flag) //if 不能再判断 flag 程序会继续向下执行 condition_pro.await(); this.name = name + "编号:"+id++; System.out.println(Thread.currentThread().getName()+"..生产者.."+this.name); flag = true; condition_con.signal(); }finally { lock.unlock(); } } //输出资源 public void out() throws InterruptedException{ lock.lock(); try { while(!flag) condition_con.await(); System.out.println(Thread.currentThread().getName()+"..消费者.."+this.name); flag = false; condition_pro.signal(); }finally { lock.unlock(); } } } class Producer2 implements Runnable { Resource2 r; public Producer2(Resource2 r) { this.r = r; } public void run() { while(true) try { r.set("大米"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class Consumer2 implements Runnable { Resource2 r; public Consumer2(Resource2 r) { this.r = r; } public void run(){ while(true) try { r.out(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public class ProducerConsumerDemo2 { public static void main(String[] args) { Resource2 r = new Resource2(); new Thread(new Producer2(r)).start(); new Thread(new Producer2(r)).start(); new Thread(new Consumer2(r)).start(); new Thread(new Consumer2(r)).start(); } }
线程的停止
package day12; /** * 线程的停止 * @author hao * *老版本的stop方法已经过时,如何停止线程 *多线程的运行,一般采用循环结构。只要控制好循环, *就可以让run方法结束,随之线程就结束啦 * *特殊情况: *当线程处于冻结状态 *就不会读取到标记。那么线程就不会结束 * *当没有指定的方式让冻结的线程恢复到运行状态时,这是需要对冻结进行清除 *强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。 * *Thread类提供该方法interrupt(); */ class StopThread implements Runnable { 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 StopThreadDemo { 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"); } }
Thread其他方法
package day12; /** * join 方法的应用 线程的优先级 * @author hao * *如果A线程在B线程之前 A线程采用的join方法 B线程需要等待A线程运行完才能运行 * *join可以用来临时加入线程 * *下面程序运行结果一部分: * Thread-0..57 Thread-0..58 Thread-0..59 main0 main1 main2 main3 main4 Thread-1..0 Thread-1..1 * *public final void setPriority(int newPriority) *更改线程的优先级。 * *public static void yield() *暂停当前正在执行的线程对象,并执行其他线程。 */ class Demo implements Runnable { public void run() { for(int i = 0; i < 60; i++) { System.out.println(Thread.currentThread().getName()+".."+i); } } } public class JoinDemo { public static void main(String[] args) throws InterruptedException { Demo d = new Demo(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); //t1.setPriority(Thread.MAX_PRIORITY); t2.start(); //t1.join(); for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName()+i); } } }
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
相关文章推荐
- 黑马程序员_线程知识总结
- 黑马程序员-线程
- 黑马程序员-线程(两种创建方式)、定时器
- 黑马程序员-关于线程学习的若干总结
- 黑马程序员 线程状态以及概述应用
- 黑马程序员 让某个线程结束的几种方法
- 黑马程序员——多线程之线程安全的实现详解
- 黑马程序员 关于c# windows窗体关闭时线程未能完全退出问题(专题一)
- 黑马程序员 线程状态
- 黑马程序员---线程间通讯
- 黑马程序员——第七天(线程间通信)
- 黑马程序员—— 线程基础总结
- 黑马程序员_java线程进阶
- 黑马程序员_线程间的通信
- 黑马程序员--线程之间的通信,等待与唤醒机制,线程的终止方式,线程中的其他方法,优先级,toString() 守护线程,GUI图形化界面
- 黑马程序员 _Java中的进程、线程和多线程
- 黑马程序员——JAVA基础——线程---概述,创建、生命周期,控制,同步,线程通信
- 黑马程序员_java基础二(线程和集合)
- 黑马程序员--.Net学习日记——线程
- 黑马程序员_进程和线程的区别