博客
关于我
线程(下)--线程通信&&消费者问题
阅读量:285 次
发布时间:2019-03-03

本文共 7033 字,大约阅读时间需要 23 分钟。

线程通信

就是多个线程之间相互牵制,相互调度执行

wait();让线程等待,进入阻塞状态,不会自动唤醒

notify();唤醒等待的线程,如果有多个,那就唤醒优先级高的

notifyAll();唤醒所有等待的线程

案例:交替打印1-100的数

1.使用lock锁,实现Runnable的方法

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class PrintNum implements Runnable {       static int num = 0;    static Lock lock = new ReentrantLock();    static Condition con = lock.newCondition();    @Override    public void run() {           while (true) {               try {                   lock.lock();                con.signal();//唤醒线程                num++;                if (num <= 100) {                       System.out.println(Thread.currentThread().getName() + ":" + num);                } else {                       lock.unlock();                    break;                }                con.await();//线程等待,并释放锁                lock.unlock();            } catch (InterruptedException e) {                   e.printStackTrace();                lock.unlock();            }        }    }}

测试类

public class Test {       public static void main(String[] args) {           PrintNum p =new PrintNum();        Thread p1 = new Thread(p);        Thread p2 = new Thread(p);        p1.start();        p2.start();    }}

2.实现Runnable的方法,使用synchronize修饰同步代码块

public class PrintNum implements Runnable{       static int num=0;    @Override    public void run() {           while (true){               synchronized (this){   //implements Runnable 情况下,this只有一个,this可以充当锁                this.notify();//唤醒等待线程 使用锁对象来调用notify(),wait();                if (num<=100){                       System.out.println(Thread.currentThread().getName()+":"+num);                    num++;                }else{                       break;                }                try {                       this.wait();//线程等待,并释放锁                } catch (InterruptedException e) {                       e.printStackTrace();                }            }        }    }}

测试类

public class Test {       public static void main(String[] args) {           PrintNum p =new PrintNum();        Thread p1 = new Thread(p);        Thread p2 = new Thread(p);        p1.start();        p2.start();    }}

3.继承Thread类的方法,使用synchronize修饰同步代码块

public class PrintNum extends Thread {       static int num = 0;    static Object obj =new Object();//继承Thread方式,由于创建了多个对象,需要自己创建一个唯一的对象,充当锁    @Override    public void run() {           while (true) {               synchronized (obj) {                   obj.notify();                if (num <= 100) {                       System.out.println(Thread.currentThread().getName() + ":" + num);                    num++;                } else {                       break;                }                try {                       obj.wait();                } catch (InterruptedException e) {                       e.printStackTrace();                }            }        }    }}

测试类

public class Test {       public static void main(String[] args) {           PrintNum p1 = new PrintNum();        PrintNum p2 = new PrintNum();        p1.start();        p2.start();    }}

消费者生产者问题

1.柜台类,存放物品的类

/*柜台中 存放共享数据*/public class Counter {       int num = 0;//初始物品数量为0    /* 生产商品*/    public synchronized void add() {           if (num == 0) {               num++;            System.out.println("生产一个");            this.notify();//唤醒消费者线程  this表示同一个柜台        } else {               try {                   this.wait();//生产者等待            } catch (InterruptedException e) {                   e.printStackTrace();            }        }    }    /*消费商品 */    public synchronized void sub() {           if (num == 1) {               num--;            System.out.println("消费一个");            this.notify();//唤醒生产者线程  this表示同一个柜台        } else {               try {                   this.wait();//消费者等待            } catch (InterruptedException e) {                   e.printStackTrace();            }        }    }}

2.生产者线程

public class Productor extends Thread {       Counter c;    public Productor(Counter c) {           this.c = c;    }    @Override    public void run() {           while (true) {               try {                   Thread.sleep(1000);//休眠指定的时间                c.add();//调用add方法            } catch (InterruptedException e) {                   e.printStackTrace();            }        }    }}

3.消费者线程

/*消费者线程*/public class Customer extends Thread {       Counter c;    public Customer(Counter c) {           this.c = c;    }    @Override    public void run() {           while (true) {               try {                   Thread.sleep(1000);                c.sub();            } catch (InterruptedException e) {                   e.printStackTrace();            }        }    }}

4.测试类

public class Test {       public static void main(String[] args) {           Counter c = new Counter();//创建柜台对象,是生产或者和消费者        Productor p = new Productor(c);        Customer ct = new Customer(c);        p.start();        ct.start();    }}

jdk8以后的两种创建线程的方法

以1-100求和问题

1.FutureTask用来接受任务

import java.util.concurrent.Callable;public class SumNumThread implements Callable
{ /* 可以向外界返回一个结果 可以抛出一个异常 */ @Override public Integer call() throws Exception { int sum=0; for (int i = 1; i <= 100;i++){ sum+=i; } return sum; }}
public class Test {       public static void main(String[] args) {           //创建任务        SumNumThread sum = new SumNumThread();        //接受任务        FutureTask
futureTask = new FutureTask(sum); //创建线程 Thread t = new Thread(futureTask); t.start(); try { Integer val = futureTask.get(); System.out.println(val); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}

2.ExecutorService创建线程池

public class SumNumThread implements Callable
{ /* 可以向外界返回一个结果 可以抛出一个异常 */ @Override public Integer call() throws Exception { int sum=0; System.out.println(Thread.currentThread().getName()); for (int i = 1; i <= 100;i++){ sum+=i; } return sum; }}
public class Test {       public static void main(String[] args) {           ExecutorService executorService = Executors.newFixedThreadPool(5);        SumNumThread sumNumThread = new SumNumThread();        //将任务交给线程池中线程执行        //线程池中线程不够时,会释放其中的重复利用        executorService.submit(sumNumThread);        executorService.submit(sumNumThread);        executorService.submit(sumNumThread);        executorService.submit(sumNumThread);        executorService.submit(sumNumThread);        Future
f = executorService.submit(sumNumThread); try { System.out.println(f.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } executorService.shutdown(); }}

转载地址:http://noul.baihongyu.com/

你可能感兴趣的文章
mysql长事务
查看>>
mysql问题记录
查看>>
mysql间隙锁
查看>>
MySQL集群解决方案(1):MySQL数据库的集群方案
查看>>
MySQL集群解决方案(2):主从复制架构
查看>>
MySQL集群解决方案(3):MyCat中间件
查看>>
MySQL集群解决方案(4):负载均衡
查看>>
MySQL集群解决方案(5):PXC集群
查看>>
MySQL面试宝典
查看>>
WAP短信:融合传统短信和互联网的新型通信方式
查看>>
mysql面试题学校三表查询_mysql三表查询分组后取每组最大值,mysql面试题。
查看>>
Mysql面试题精选
查看>>
MySQL面试题集锦
查看>>
mysql面试题,存储引擎InnoDB和MyISAM
查看>>
mysql面试题:为什么MySQL单表不能超过2000W条数据?
查看>>
mysql面试题:创建索引时会不会锁表?
查看>>
mysql面试题:高度为3的B+树可以存放多少数据?
查看>>
mysql颠覆实战笔记(八)--mysql的自定义异常处理怎么破
查看>>
mysql驱动、durid、mybatis之间的关系
查看>>
mysql驱动支持中文_mysql 驱动包-Go语言中文社区
查看>>