线程二

1、线程间通讯
就是多个线程在操作同一个资源,但是操作的动作不同。
多线程同步时千万注意同步前提:
使用同步原则一、线程:必须要有两个或者以上的线程; 使用同步原则二、锁:必须是多个线程使用同一个锁。
使用同步原则三、独:必须保证同步中只能有一个线程在运行。

class Resource{
 String name;
 String sex; 
}
class Input implements Runnable{
 private Resource r;
 Input(Resource r){
  this.r = r; 
 } 
 public void run(){
  int x= 0;
  while(true){
   synchronized(r){//使用同步原则二、锁为同一个锁
    if(x==0){
     r.name = "lili";
     r.sex = "girl"; 
    } else{
     r.name = "龟龟";
     r.sex = "男"; 
    }
    x = (x+1)%2;
   }
  } 
 }
}
class Output implements Runnable{
 private Resource r;
 Output(Resource r){
  this.r = r; 
 } 
 public void run(){
  while(true){
   synchronized(r){//使用同步原则二、锁为同一个锁
    System.out.println(r.name+"******"+r.sex);
   }
  } 
 }
}
class InputOutputDemo03{
 public static void main(String[] args){
  Resource r = new Resource();
  
  Input in = new Input(r);
  Output out = new Output(r);
  
  Thread t1 = new Thread(in);
  Thread t2 = new Thread(out);
  
  t1.start();
  t2.start(); 
 } 
}



2、等待唤醒机制
wait()、notify()、notifyAll()
第一、这些方法都用在同步中原因:用在都使用在同步中,因为要对持有监视器(锁)的线程操作,所以要使用在同步中。
第二、这些方法都定义在Object类中原因:因为这些方法操作同步中线程时,都必须要标识他们所操作线程持有的锁,只有同一个锁上的被等待线程wait,可以被同一个锁上notify唤醒。不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象 ,所以可以被任意对象调用的方法定义在Object类中。

class Resource{
 private String name;
 private String sex; 
 private boolean flag = false;
 public synchronized void set(String name,String sex){
  if(flag){
   try{this.wait();}catch(Exception e){} 
  }
  this.name = name;
  this.sex = sex; 
  flag = true;
  this.notify();
 }
 public synchronized void out(){
  if(!flag){
   try{this.wait();}catch(Exception e) {} 
  }
  System.out.println(name+"****"+sex); 
  flag = false;
  this.notify();
 }
}
class Input implements Runnable{
 private Resource r;
 Input(Resource r){
  this.r = r; 
 } 
 public void run(){
  int x= 0;
  while(true){
   synchronized(r){//使用同步原则二、锁为同一个锁
    
    if(x==0){
     r.set("lili","girl");
    } else{
     r.set("龟龟","男"); 
    }
    x = (x+1)%2;
   }
  } 
 }
}
class Output implements Runnable{
 private Resource r;
 Output(Resource r){
  this.r = r; 
 } 
 public void run(){
  while(true){
   r.out();
  } 
 }
}
class InputOutputDemo03{
 public static void main(String[] args){
  Resource r = new Resource();
  
  new Thread(new Input(r)).start();
  new Thread(new Output(r)).start();
  
  /*Input in = new Input(r);
  Output out = new Output(r);
  
  Thread t1 = new Thread(in);
  Thread t2 = new Thread(out);
  
  t1.start();
  t2.start(); */
 } 
}



3、线程间通信---生产者消费者JDK5.0升级版
JDK1.5中提供了多线程升级解决方案:
将同步Synchronized替换成Lock操作;======》方便知道是什么时候锁、什么时候解锁
将Object中的wait\notify\notifyAll替换成Condition对象;======》可以唤醒对方锁对象

import java.util.concurrent.locks.*;
public class ProducerComsumerDemo02{
 public static void main(String[] args){
  Resource r = new Resource();
  
  Producer pro = new Producer(r);
  Consumer con = new Consumer(r);
  
  Thread t1 = new Thread(pro);
  Thread t2 = new Thread(pro);
  Thread t3 = new Thread(con);
  Thread t4 = new Thread(con);
  
  t1.start();
  t2.start();
  t3.start();
  t4.start(); 
 } 
}
class Resource{
 private String name;
 private int count = 1;
 private 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){
    condition_pro.await(); 
   } 
   this.name = name+"***"+count++;
   
   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 Producer implements Runnable{
  private Resource res;
  Producer(Resource res){
   this.res = res; 
  }
  public void run(){
   while(true){
    try{
     res.set("+商品+");
    } catch(InterruptedException e){}
   } 
  }
}
class Consumer implements Runnable{
 private Resource res;
 Consumer(Resource res){
  this.res = res; 
 } 
 public void run(){
  while(true){
   try{
     res.out();
   } catch(InterruptedException e){}
  } 
 }
}



4、停止线程
停止线程,stop方法已经过时。这时如何停止线程?只有一种方法,就是run方法结束。
开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以让run方法结束,也就是线程结束。
特殊情况:当线程处于冻结状态,就不会读取标记,那么线程就不会结束。
当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除,强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。Thread类提供方法interrupt()。

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 StopThreadDemo{
 public static void main(String[] args){
  StopThread st = new StopThread();
  
  Thread t1 = new Thread(st);
  Thread t2 = new Thread(st);
  t1.start();
  t2.start();
  int num = 0;
  while(true){
   if(num++ == 60){
    t1.interrupt();
    t2.interrupt();
    break; 
   } 
   System.out.println(Thread.currentThread().getName()+";;;;"+num);
  } 
  System.out.println("over");
 } 
}



5、守护线程
public final void setDaemon(boolean on)
将该线程标记为守护线程或者用户线程,当正在运行的线程都是守护线程时,java虚拟机退出。
6、join方法
当A线程执行到了B线程.jion()方法时,A就会等待。等B线程都执行完,A才会执行。jion可以用来临时加入线程执行。

总结:
线程通讯
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值