ASP.Net+Android+IOS开发 、Net培训、期待与您交流!
(前言:本篇文章主要依据毕向东老师的课程视频整理而成,如要详细学习,请观看毕老师视频 百度网盘链接地址:http://pan.baidu.com/s/1sjQRHDz)
目录:1、线程通信--生产消费者示例(线程通信安全、等待唤醒机制) 2、停止线程、及其会出现的问题、及解决的办法 3、守护线程及几个Thread的方法 4、工作中线程的常见写法
1、线程通信--生产消费者示例
代码示例:
1 public class ProducerConsumer { 2 //需求:生产和消费行为依次进行。 设置产品为BMW 设置生产者和消费者线程各两个 3 public static void main(String[] args) { 4 5 Product pro=new Product(); 6 7 new Thread(new Producter(pro)).start(); 8 new Thread(new Consumer(pro)).start(); 9 new Thread(new Producter(pro)).start();10 new Thread(new Consumer(pro)).start();11 12 }13 }14 class Product{15 16 private String name;17 private int No=1;18 boolean flag=false;19 20 public synchronized void set(String names){21 while(flag)22 try {23 this.wait();//等待状态 24 } catch (InterruptedException e) {25 e.printStackTrace();26 } 27 this.name=names+"---"+this.No++;28 System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产"); 29 flag=true;30 this.notifyAll();//唤醒所有线程31 } 32 public synchronized void out(){33 while(!flag)34 try {35 this.wait();//等待状态36 } catch (InterruptedException e) {37 e.printStackTrace();38 } 39 System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------"); 40 flag=false;41 this.notifyAll();//唤醒所有线程42 }43 }44 //生产者45 class Producter implements Runnable{46 private Product p;47 public Producter(Product pr){48 this.p=pr;49 }50 public void run(){ 51 while(true){52 p.set("BMW");53 }54 } 55 }56 //消费者57 class Consumer implements Runnable{58 private Product p;59 public Consumer(Product pr){60 this.p=pr;61 } 62 public void run(){ 63 while(true){64 p.out();65 }66 }67 }
使用JDK5.0新特性改进后的代码
1 /*JDK5.0后增加了Lock 和Condition新类特性来取代 同步和锁的繁琐操作 */ 2 public class ProducerConsumerNew { 3 4 public static void main(String[] args) { 5 6 Product pro=new Product(); 7 8 new Thread(new Producter(pro)).start(); 9 new Thread(new Consumer(pro)).start();10 new Thread(new Producter(pro)).start();11 new Thread(new Consumer(pro)).start();12 13 }14 15 }16 class ProductNew{ 17 private String name;18 private int No=1;19 boolean flag=false;20 21 private Lock lock=new ReentrantLock();22 private Condition con1=lock.newCondition();23 private Condition con2=lock.newCondition();24 25 public void set(String name){26 27 while(flag)28 try {29 lock.lock();30 con1.wait();31 } catch (InterruptedException e) {32 e.printStackTrace();33 }finally{34 lock.unlock();35 }36 this.name=name+"---"+this.No++; 37 System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产");38 39 this.flag=true;40 con2.signal();41 }42 43 public void out(){ 44 while(!this.flag)45 try {46 lock.lock();47 con2.wait();48 } catch (InterruptedException e) {49 e.printStackTrace();50 }finally{51 lock.unlock();52 con1.signal();53 } 54 System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------");55 56 this.flag=false;57 }58 }59 //生产者60 class ProducterNew implements Runnable{61 private ProductNew p;62 public ProducterNew(ProductNew pr){63 this.p=pr;64 }65 public void run(){66 while(true){67 p.set("BMW");68 }69 } 70 }71 //消费者72 class ConsumerNew implements Runnable{73 private ProductNew p;74 public ConsumerNew(ProductNew pr){75 this.p=pr;76 } 77 public void run(){78 while(true)79 p.out();80 }81 }
2、停止线程、及其会出现的问题、及解决的办法
停止线程思路:开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以让run()方法结束,线程即结束。
特殊情况:当线程处于冻结状态(wait()),就不会读取到标记,那么线程就不会结束。
解决办法:当没有指定的方式让冻结的线程恢复到运行状态时,需要用Interrupt()方法强制清除冻结状态,再用操作标记让线程结束
一个简单的代码例子
1 public class ThreadStop { 2 3 public static void main(String[] args) { 4 5 ThreadTt tt=new ThreadTt(); 6 7 Thread th1=new Thread(tt); 8 Thread th2=new Thread(tt); 9 th1.start();10 th2.start();11 int count=0;12 while(true){13 if(++count>60){ //循环来控制线程的结束14 th1.interrupt(); //强制清除线程冻结状态15 th2.interrupt();16 break;17 }18 System.out.println(Thread.currentThread().getName()+"....run---"+count);19 } 20 System.out.println(Thread.currentThread().getName()+"....over");21 }22 }23 class ThreadTt implements Runnable{24 25 boolean flag=true;26 Lock lock=new ReentrantLock();27 Condition con=lock.newCondition();28 public synchronized void run() {29 30 while(flag){31 try {32 wait(); //用这个方法让线程处于冻结状态33 } catch (InterruptedException e) {34 System.out.println(e.getStackTrace());35 flag=false;36 }37 System.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、工作中线程的常见写法(用到内部类)
不多说,看代码
1 public class ThreadStand { 2 3 public static void main(String[] args) { 4 //工作中多线程的常见写法,构建内部类 5 new Thread(){ 6 public void run(){ 7 for(int i=0;i<100;i++) 8 System.out.println(Thread.currentThread().getName()+"....run...."+i); 9 }10 }.start();11 12 for(int i=0;i<100;i++)13 System.out.println(Thread.currentThread().getName()+"....run...."+i);14 15 //构造内部类16 Runnable rn= new Runnable(){17 public void run() {18 for(int i=0;i<100;i++)19 System.out.println(Thread.currentThread().getName()+"....run...."+i); 20 }21 }; 22 new Thread(rn).start(); 23 }24 }
初学者难免错误,欢迎评判指教,持续更正ing...........
ASP.Net+Android+IOS开发 、Net培训、期待与您交流!