博客
关于我
线程(下)--线程通信&&消费者问题
阅读量: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学习总结(26)——MySQL子查询
查看>>
Mysql学习总结(37)——Mysql Limit 分页查询优化
查看>>
Mysql学习总结(38)——21条MySql性能优化经验
查看>>
Mysql学习总结(45)——Mysql视图和事务
查看>>
Mysql学习总结(58)——深入理解Mysql的四种隔离级别
查看>>
Mysql客户端中文乱码问题解决
查看>>
Mysql工作笔记006---Mysql服务器磁盘爆满了_java.sql.SQLException: Error writing file ‘tmp/MYfXO41p‘
查看>>
Mysql建立中英文全文索引(mysql5.7以上)
查看>>
MySQL当查询的时候有多个结果,但需要返回一条的情况用GROUP_CONCAT拼接
查看>>
MySQL必知必会总结笔记
查看>>
MySQL快速入门——库的操作
查看>>
mysql快速复制一张表的内容,并添加新内容到另一张表中
查看>>
mysql怎么删除临时表里的数据_MySQL中关于临时表的一些基本使用方法
查看>>
mysql性能测试工具选择 mysql软件测试
查看>>
MySQL慢查询-开启慢查询
查看>>
MySQL慢查询日志总结
查看>>
MySQL慢查询问题排查
查看>>
mysql截取sql语句
查看>>
mysql手工注入
查看>>
Mysql执行update by id的过程
查看>>