java基础--12

强颜欢笑 提交于 2020-04-02 14:14:53

1、线程间通信--示例代码
 其实就是多个线程在操作同一个资源,但是操作的动作不同
2、解决安全问题
3、等待唤醒机制
 wait()
 notify()
 notifyall()
 都使用在同步中,因为要对持有监视器(锁)的线程操作

 为什么这些操作线程的方法要定义在Object类中呢?
  因为这些方法在操作同步中线程时,都必须要标识他们所操作线程持有的锁,
  只有同一个锁上的被等待线程可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒
  也就是说等待和唤醒必须是同一个锁。
  而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中
 public class InputOutputDemo
{
 public static void main(String[] args)
 {
  Res r=new Res();
  Input input=new Input(r);
  Output output=new Output(r);
  Thread t1=new Thread(input);
  Thread t2=new Thread(output);
  t1.start();
  t2.start();
 }
}

class Res
{
 String name;
 String sex;
 boolean flag=false;
}

class Input implements Runnable
{
 private Res r;
 Input(Res r)
 {
  this.r=r;
 }
 
 
 public void run()
 {
  int x=0;
  while(true)
  {
   synchronized(r)
   { 
    if(r.flag)
    {
     try{r.wait();}catch(Exception t){}
    }
    if(x==0)
    {
     r.name="mike";
     r.sex="man";
    }
    else
    {
     r.name="丽丽";
     r.sex="女";
    }
    x=(x+1)%2;
    r.flag=true;
    r.notify();
   }
  }
 }
}

class Output implements Runnable
{
 private Res r;
 Output(Res r)
 {
  this.r=r;
 }
 
 public void run()
 {
  while(true)
  {
   synchronized(r)
   {
    if(!r.flag)
    {
     try{r.wait();}catch(Exception t){}
    }
    System.out.println(r.name+"..."+r.sex);
    r.flag=false;
    r.notify();
   }
  }
 }
}
4、代码优化
 public class InputOutputDemo2
{
 public static void main(String[] args)
 {
  Res r=new Res();
  new Thread(new Input(r)).start();
  new Thread(new Output(r)).start();
 }
}

class Res
{
 private String name;
 private String sex;
 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 get()
 {
  if(!flag)
  {try{this.wait();}catch(Exception e){}}
  System.out.println(name+"..."+sex);
  flag=false;
  this.notify();
 }
}

class Input implements Runnable
{
 private Res r;
 Input(Res r)
 {
  this.r=r;
 }
 
 public void run()
 {
  int x=0;
  while(true)
  {
   if(x==0)
   {
    r.set("mike","man");
   }
   else
   {
    r.set("丽丽","女");
   }
   x=(x+1)%2;
  }
 }
}

class Output implements Runnable
{
 private Res r;
 Output(Res r)
 {
  this.r=r;
 }
 
 public void run()
 {
  while(true)
  {
   r.get();
  }
 }
}
5、生产者消费者问题
 public class ProducerConsumerDemo
{
 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;
 private boolean flag=false;
 
 public synchronized void set(String name)
 {
  while(flag)
  {
   try{this.wait();}catch(Exception e){}
  }
  this.name=name+"--"+count++;
  System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
  flag=true;
  this.notifyAll();
 }
 
 public synchronized void get()
 {
  while(!flag)
  {
   try{this.wait();}catch(Exception e){}
  }
  System.out.println(Thread.currentThread().getName()+"...消费者..."+this.name);
  flag=false;
  this.notifyAll();
 }
}

class Producer implements Runnable
{
 private Resource r;
 Producer(Resource r)
 {
  this.r=r;
 }
 public void run()
 {
  while(true)
  {
   r.set("商品");
  }
 }
}

class Consumer implements Runnable
{
 private Resource r;
 Consumer(Resource r)
 {
  this.r=r;
 }
 public void run()
 {
  while(true)
  {
   r.get();
  }
 }
}
6、生产者jdk5.0
 jdk1.5中提供了多线程的升级解决方案,将同步synchronized替换成显示的lock操作
 将Object中的wait,notify,notifyAll替换成了Condition对象,该对象可以Lock锁进行获取
 该例中,实现了本方唤醒对方操作。
 import java.util.concurrent.locks.*;

public class ProducerConsumerDemo2
{
 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(con);
  t1.start();
  t2.start();
 }
}

class Resource
{
 private String name;
 private int count;
 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()+"生产者"+name);
    flag=true;
    condition_con.signal();
   }
   finally
   {
    lock.unlock();
   }
  
 }
 
 public void get()throws InterruptedException
 {
  
   lock.lock();
   try
   {
    while(!flag)
    {
     condition_con.await();
    }
    System.out.println(Thread.currentThread().getName()+"消费者"+name);
    flag=false;
    condition_pro.signal();
   }
   finally
   {
    lock.unlock();
   }
  
 }
}

class Producer implements Runnable
{
 private Resource r;
 Producer(Resource r)
 {
  this.r=r;
 }
 
 public void run()
 {
  while(true)
  {
   try
   {
    r.set("商品");
   }
   catch(InterruptedException e)
   {}
  }
 }
}

class Consumer implements Runnable
{
 private Resource r;
 Consumer(Resource r)
 {
  this.r=r;
 }
 
 public void run()
 {
  while(true)
  {
   try
   {
    r.get();
   }
   catch(InterruptedException e)
   {}
  }
 }
}
7、停止线程
 stop方法已经过时
 停止线程只有一种方法,run方法结束
 开启多线程运行,运行代码通常都是循环结构。
 只要控制住循环,就可以让run方法结束,也就是让线程结束。

 当没有指定的方式让冻结的线程恢复到运行状态时,需要对冻结进行清除
 强制让线程恢复到运行状态中来。这样就可以操作标记让线程结束
 Thread类中提供了方法 interrupt();
8、守护线程
 setDaemon(true)
9、join方法
 当A线程执行到了B线程的join方法时,那么A线程就回等待,等B线程都执行完,A才执行。
 join可以用来临时加入线程执行。
10、优先级&yield方法
 setPriority(Thread.MAX_PRIORITY);
 Thread.yield();

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!