黑马程序员系列第二篇多线程(2)

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

asp.net+Android+IOS开发 、Net培训、期待与您交流!

(前言:本篇文章主要依据毕向东老师的课程视频整理而成,如要详细学习,请观看毕老师视频 百度网盘链接地址:http://pan.baidu.com/s/1i3m6DrJ)

目录:1、线程通信--生产消费者示例(线程通信安全、等待唤醒机制) 2、停止线程、及其会出现的问题、及解决的办法 3、守护线程及几个Thread的方法 4、工作中线程的常见写法

1、线程通信--生产消费者示例

代码示例:

publicclassPRoducerConsumer {//需求:生产和消费行为依次进行。 设置产品为BMW 设置生产者和消费者线程各两个publicstaticvoidmain(String[] args) {

Product pro=newProduct();newThread(newProducter(pro)).start();newThread(newConsumer(pro)).start();newThread(newProducter(pro)).start();newThread(newConsumer(pro)).start();

}

}classProduct{privateString name;privateintNo=1;booleanflag=false;publicsynchronizedvoidset(String names){while(flag)try{this.wait();//等待状态}catch(InterruptedException e) {

e.printStackTrace();

}this.name=names+"---"+this.No++;

System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产");

flag=true;this.notifyAll();//唤醒所有线程}publicsynchronizedvoidout(){while(!flag)try{this.wait();//等待状态}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------");

flag=false;this.notifyAll();//唤醒所有线程}

}//生产者classProducterimplementsRunnable{privateProduct p;publicProducter(Product pr){this.p=pr;

}publicvoidrun(){while(true){

p.set("BMW");

}

}

}//消费者classConsumerimplementsRunnable{privateProduct p;publicConsumer(Product pr){this.p=pr;

}publicvoidrun(){while(true){

p.out();

}

}

}

使用JDK5.0新特性改进后的代码

1/*JDK5.0后增加了Lock 和Condition新类特性来取代 同步和锁的繁琐操作*/2publicclassProducerConsumerNew {34publicstaticvoidmain(String[] args) {56Product pro=newProduct();78newThread(newProducter(pro)).start();9newThread(newConsumer(pro)).start();10newThread(newProducter(pro)).start();11newThread(newConsumer(pro)).start();1213}1415}16classProductNew{17privateString name;18privateintNo=1;19booleanflag=false;2021privateLock lock=newReentrantLock();22privateCondition con1=lock.newCondition();23privateCondition con2=lock.newCondition();2425publicvoidset(String name){2627while(flag)28try{29lock.lock();30con1.wait();31}catch(InterruptedException e) {32e.printStackTrace();33}finally{34lock.unlock();35}36this.name=name+"---"+this.No++;37System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产");3839this.flag=true;40con2.signal();41}4243publicvoidout(){44while(!this.flag)45try{46lock.lock();47con2.wait();48}catch(InterruptedException e) {49e.printStackTrace();50}finally{51lock.unlock();52con1.signal();53}54System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------");5556this.flag=false;57}58}59//生产者60classProducterNewimplementsRunnable{61privateProductNew p;62publicProducterNew(ProductNew pr){63this.p=pr;64}65publicvoidrun(){66while(true){67p.set("BMW");68}69}70}71//消费者72classConsumerNewimplementsRunnable{73privateProductNew p;74publicConsumerNew(ProductNew pr){75this.p=pr;76}77publicvoidrun(){78while(true)79p.out();80}81}

2、停止线程、及其会出现的问题、及解决的办法

停止线程思路:开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以让run()方法结束,线程即结束。

特殊情况:当线程处于冻结状态(wait()),就不会读取到标记,那么线程就不会结束。

解决办法:当没有指定的方式让冻结的线程恢复到运行状态时,需要用Interrupt()方法强制清除冻结状态,再用操作标记让线程结束

一个简单的代码例子

1publicclassThreadStop {23publicstaticvoidmain(String[] args) {45ThreadTt tt=newThreadTt();67Thread th1=newThread(tt);8Thread th2=newThread(tt);9th1.start();10th2.start();11intcount=0;12while(true){13if(++count>60){//循环来控制线程的结束14th1.interrupt();//强制清除线程冻结状态15th2.interrupt();16

break;17}18System.out.println(Thread.currentThread().getName()+"....run---"+count);19}20System.out.println(Thread.currentThread().getName()+"....over");21}22}23classThreadTtimplementsRunnable{2425booleanflag=true;26Lock lock=newReentrantLock();27Condition con=lock.newCondition();28publicsynchronizedvoidrun() {2930while(flag){31try{32wait();//用这个方法让线程处于冻结状态33}catch(InterruptedException e) {34System.out.println(e.getStackTrace());35flag=false;36}37System.out.println(Thread.currentThread().getName()+"...run");38}39}40}

3、守护线程及几个Thread的方法

守护线程/用户线程:通俗而言为”后台进程”,当前台进程都结束时,后台进程自动结束;当正在运行的线程都是守护线程时,JVM自动退出。

setDaemon()方法设置守护线程,该方法必须在启动线程前调用

Join()方法 特点:当A线程执行到了B线程的jion()方法是,A就会等待,等B线程都执行完以后,A才会执行。Jion可以用来临时加入线程执行 线程抢夺cpu执行权

ToString()方法

setPriority()方法 更改线程的优先级,优先级代表抢夺资源的频率高低

Yield()方法 暂停当前线程的执行,去执行其它线程

4、工作中线程的常见写法(用到内部类)

不多说,看代码

1publicclassThreadStand {23publicstaticvoidmain(String[] args) {4//工作中多线程的常见写法,构建内部类5newThread(){6publicvoidrun(){7for(inti=0;i<100;i++)8System.out.println(Thread.currentThread().getName()+"....run...."+i);9}10}.start();1112for(inti=0;i<100;i++)13System.out.println(Thread.currentThread().getName()+"....run...."+i);1415//构造内部类16Runnable rn=newRunnable(){17publicvoidrun() {18for(inti=0;i<100;i++)19System.out.println(Thread.currentThread().getName()+"....run...."+i);20}21};22newThread(rn).start();23}24}

初学者难免错误,欢迎评判指教,持续更正ing...........

ASP.Net+Android+IOS开发 、Net培训、期待与您交流!

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航