线程(下)--线程通信&&消费者问题
发布日期:2021-05-06 03:20:45 浏览次数:10 分类:技术文章

本文共 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(); }}
上一篇:GUI编程--图形用户界面
下一篇:线程(中)

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年03月18日 22时01分36秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

2021年高处安装、维护、拆除考试资料及高处安装、维护、拆除证考试 2019-03-03
2021年电工(初级)考试及电工(初级)证考试 2019-03-03
2021年安全员-B证-项目负责人(广东省)新版试题及安全员-B证-项目负责人(广东省)考试试卷 2019-03-03
2021年R2移动式压力容器充装考试总结及R2移动式压力容器充装模拟考试 2019-03-03
2021年安全员-B证(山东省)找解析及安全员-B证(山东省)考试总结 2019-03-03
2021年安全员-B证(山东省)考试APP及安全员-B证(山东省)考试技巧 2019-03-03
2021年安全员-A证-主要负责人(广东省)复审考试及安全员-A证-主要负责人(广东省)操作证考试 2019-03-03
2021年安全员-A证(山东省)考试题及安全员-A证(山东省)报名考试 2019-03-03
2021年G1工业锅炉司炉考试报名及G1工业锅炉司炉模拟考试题库 2019-03-03
2021年G1工业锅炉司炉考试报名及G1工业锅炉司炉模拟考试题库 2019-03-03
2021年安全员-B证(山东省)考试内容及安全员-B证(山东省)模拟考试题 2019-03-03
2021年高压电工考试题库及高压电工找解析 2019-03-03
从xx离职随笔 2019-03-03
大数据学习之Spark——00Spark项目的pom.xml文件 2019-03-03
大数据学习之Spark——01Spark概述 2019-03-03
大数据学习之Spark——03Spark代码初体验(Word Count) 2019-03-03
LeetCode0234. 回文链表 2019-03-03
比特币史话·78 | 有容乃大(2): 零食售卖机 2019-03-03
比特币史话·96 | 隐私(3): 熔币重铸 2019-03-03
Filecoin主网上线,它是谁、割了谁? 2019-03-03