黑马程序员--多线程(二)

来源:互联网 发布:关于网络鬼片 编辑:程序博客网 时间:2024/05/19 13:17
------- android培训、java培训、期待与您交流! ----------

1.线程通讯

    线程通讯其实就是多个线程在操作同一个资源,但是操作的动作不同.


注意:wait();notify();notifyAll()都使用在同步中,因为要对持有监视器的线程操作,所以要使用在同步中,因为只有同步才具有锁。


线程通讯实例

  /*   生产鼠标,要求生产一个销售一个  */  class Mouse  {  private String name;  private int count=1;  private boolean b = false;  Mouse(String name)//初始化对象  {     this.name = name;  }    //定义产品类的生产功能,多过个线程去运行同一数据,需要同步  public synchronized void proc()  {      while(this.b)//当为true时,表示鼠标生产出来了,还没卖出去,需要等待    try    {  this.wait();    }    catch (Exception e)    {    }          System.out.println(name+"...生产了第...."+count+"个");  this.b = true;  this.notifyAll();//当生产出产品时,唤醒销售线程  }    public synchronized void cus()  {      while(!this.b)  try  {  this.wait();  }  catch (Exception e)  {  }  System.out.println(name+"...消费了第"+count+"个");  count++;  this.b=false;  this.notifyAll();//销售后唤醒生产线程  }  }  //建立产品对象  class Proc implements Runnable  {  Mouse m = null;  Proc(Mouse m)  {     this.m=m;  }  public void run()  {      while(true)  {     m.proc();  }  }  }  class Cus implements Runnable  {  Mouse m = null;  Cus(Mouse m)  {     this.m=m;  }  public void run()  {  while(true)  {    m.cus();  }  }  }  class  ProcCusDemo  {  public static void main(String[] args)   {  Mouse m = new Mouse("鼠标");  Proc p = new Proc(m);          Cus c = new Cus(m);  Thread t1 = new Thread(p);  Thread t2 = new Thread(c);  Thread t3 = new Thread(p);  Thread t4 = new Thread(c);    t1.start();  t2.start();  t3.start();  t4.start();    }  }

2.中断线程 

    通过让run方法结束可以停止线程,需要在run方法中定义一个结束标记,但是如果线程处于了冻结状态,就无法读取结束标记,线程就不会结束,这时需要使用interrupt()对线程的冻结状态进行清除.    

    interrupt():如果线程在调用Object类的wait()、join()、sleep(long)方法过程中受阻,则其中断状态将被清除(使线程恢复到运行状态),它还将收到一个InterruptedException.

3.守护线程

    setDaemon():将该线程标记为守护线程或用户线程,守护线程就相当于后台线程,当前台线程结束时,后台线程跟着也结束.

class StopThread implements Runnable{public  void run()//原本run方法是一个死循环,但是将线程定义为守护线程后,主线程结束,访问run方法的线程立即也结束了{while(true){System.out.println(Thread.currentThread().getName()+"....run");}}}class  StopThreadDemo{public static void main(String[] args) {StopThread st = new StopThread();Thread t1 = new Thread(st);Thread t2 = new Thread(st);//将t1,t2定义为守护线程t1.setDaemon(true);t2.setDaemon(true);t1.start();t2.start();int num = 0;while(true){if(num++ == 60){break;}System.out.println(Thread.currentThread().getName()+"......."+num);}System.out.println("over");}}

4.join()

    join()其实就是抢夺cpu的执行权,当A线程执行到了B线程的.join()方法时,A就会等待,等B线程都执行完,A才会继续执行.

class Demo implements Runnable{public void run(){for(int x=0; x<70; x++){System.out.println(Thread.currentThread().getName()+"....."+x);}}}class  JoinDemo{public static void main(String[] args) throws Exception{Demo d = new Demo();Thread t1 = new Thread(d);Thread t2 = new Thread(d);t1.start();t1.join();//t1获取cpu的执行权,主线程处于冻结状态,只有t1结束主线程才能恢复运行状态t2.start();//t1.join();主线程冻结,t1,t2交替运行,t1结束,主线程才继续for(int x=0; x<80; x++){}System.out.println("over");}}

学习感悟

    个人感觉多线程这还是比较抽象的,虽然之前是学理科的,但还是很难理解线程之间的运行模式.线程的通信是一个重点,多个线程操作同一个数据,要保证先有输入才能输出,需要定义一个标示去告诉线程当前有无输入数据,有则停止输入线程开启输出线程,无则停止输出开启输入线程.