博客
关于我
线程(下)--线程通信&&消费者问题
阅读量:271 次
发布时间: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/

你可能感兴趣的文章
城市间紧急救援(dijkstra算法)
查看>>
关键活动(注释超详细!!!)
查看>>
为什么Android要采用Binder作为IPC机制?成功入职阿里
查看>>
大牛手把手带你!Flutter尽然还能有这种操作!面试建议
查看>>
如何成为一个更好的Android开发者?写给正在求职的安卓开发
查看>>
小白看完都会了!阿里云大师深入拆解Java虚拟机,看完这一篇你就懂了
查看>>
【IT之路】MySQL基础-MySQL常见操作
查看>>
【IT之路】Docker系列-CentOS Docker 安装
查看>>
【IT之路】FAQ-Hibernate报错:表不存在
查看>>
MySQL数据库
查看>>
MySQL性能优化说明
查看>>
随笔一
查看>>
DataWay四种请求类型传参说明及缓存问题
查看>>
【2020阿里云博客部署实战】如何远程连接和管理控制台基本介绍
查看>>
【2020阿里云部署实战】使用Nginx/Caddy反向代理进行域名访问
查看>>
Python:入门小笔记
查看>>
Python:变量
查看>>
Java:class4 类和对象
查看>>
Java:class5 类的重载,final,static
查看>>
解决笔记本无法连接到此网络问题(Win10)
查看>>