收藏 分享(赏)

多线程(三)计算机软件及应用it计算机专业资料PPT课件.ppt

上传人:微传9988 文档编号:3384352 上传时间:2018-10-21 格式:PPT 页数:27 大小:1.25MB
下载 相关 举报
多线程(三)计算机软件及应用it计算机专业资料PPT课件.ppt_第1页
第1页 / 共27页
多线程(三)计算机软件及应用it计算机专业资料PPT课件.ppt_第2页
第2页 / 共27页
多线程(三)计算机软件及应用it计算机专业资料PPT课件.ppt_第3页
第3页 / 共27页
多线程(三)计算机软件及应用it计算机专业资料PPT课件.ppt_第4页
第4页 / 共27页
多线程(三)计算机软件及应用it计算机专业资料PPT课件.ppt_第5页
第5页 / 共27页
点击查看更多>>
资源描述

1、,1,线程等待: Object 类中的wait() throws InterruptedException 方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。 线程唤醒: Object 类中的notify()方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的。 Object类中的notifyAll()方法,唤醒在此对象监视器上等待的所有线程。 这三个方法只能在被同步化(synchronized)的方法或代码块中调用,见生产者消费者示例,2,生产者(Producer)与消费

2、者(Consumer)的问题 生产者将产品交给店员(Clerk),而消费者从店员处取走产品,店员一次只能持有固定数量的产品,如果生产者生产了过多的产品,店员叫生产者等一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。,TestProduct.java,3,场景类TestProduct,/生产者消费者问题 public class TestProduct public static void main(String args) Clerk clerk = new Clerk(0); /生产者线程 Thread p

3、roducerThread = new Thread(new Producer(clerk); /消费者线程 Thread consumerThread = new Thread(new Consumer(clerk); producerThread.start(); consumerThread.start(); ,店员类Clerk(1),public class Clerk public int product;/现存的商品数量0-20public Clerk(int product) this.product = product;/从生产者处获取商品(进货)public synchron

4、ized void addProduct()if(this.product=20)/货满,暂停进货System.out.println(“货满,暂停进货“);try wait(); catch (InterruptedException e) e.printStackTrace();/.被唤醒后的后续代码else/可以进货this.product +;System.out.println(“从生产者处获得了第“+this.product +“个商品“);notify();/随机唤醒一个等待执行某个同步方法的对象.待续,店员类Clerk(2),/向消费者销售商品(卖货)public synchr

5、onized void sellProduct()if(this.product=0)System.out.println(“售罄,估清,等待生产者提供商品“);try wait(); catch (InterruptedException e) e.printStackTrace();/.被唤醒后的后续代码elseSystem.out.println(“向消费者销售了第“+(this.product) +“个商品“);this.product -;notify();/唤醒等待在this对象上的线程 ,消费者类Comsumer,public class Consumer implements

6、Runnableprivate Clerk clerk;public Consumer(Clerk clerk) super();this.clerk = clerk;public void run() while(true)clerk.sellProduct();/调用一个Clerk类中的同步方法try Thread.sleep(int)(Math.random()*2000); catch (InterruptedException e) e.printStackTrace(); ,生产者类Producer,public class Producer implements Runnable

7、private Clerk clerk;public Producer(Clerk clerk) super();this.clerk = clerk;public void run() while(true)clerk.addProduct();/调用一个Clerk类中的同步方法try Thread.sleep(int)(Math.random()*1000); catch (InterruptedException e) e.printStackTrace(); ,练习,Wife线程类,负责花钱1万的随机整数倍,每次不超过10万,如果余额不够但不为0,则有多少就花多少,没钱就wait; H

8、usband线程类,负责赚钱,2万的随机整数倍,每次不超过10万;如果余额超过10万(含),则wait;如果余额加上新赚的钱超过10万,则保留(例如余额5万,新赚6万,则新余额11万) Account账户类(属性:int money,下限0万元) TestMoney场景类,启动一个Husband线程,启动两个Wife线程,模拟老公赚钱,老婆花钱的过程.,java.lang.ThreadLocal 线程局部变量,用于解决多个线程共享同一个对象时,对象属性的数据安全问题. 每一个ThreadLocal对象就像一个整个楼的信箱,每一个线程只能打开其中的一个属于自己的信箱.这个信箱只能放一个对象. 本

9、质上ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本.且无需知道key是什么(其实是当前线程).也不会错用到其他线程的局部变量.,public class ThreadLocalDemo implements Runnable private final static ThreadLocal studentLocal = new ThreadLocal( ); public static void main(String agrs) ThreadLocalDemo td = new ThreadLocalDemo(); Thread t1 = new Thread(td,

10、 “a“);/td是共享数据,“a“是线程名 Thread t2 = new Thread(td, “b“); t1.start(); t2.start(); public void run() this.accessStudent();/调用一个本类中自定义的方法 . .,public Student getStudent() /获取本地线程变量 Student student = studentLocal.get(); /线程首次执行此方法的时候,studentLocal.get()肯定为null if (student = null) /创建一个Student对象,并保存到本地线程变量s

11、tudentLocal中 student = new Student(); studentLocal.set(student); return student; ,public void accessStudent() /获取当前线程的名字 String currentThreadName = Thread.currentThread().getName(); /产生一个随机数并打印 Random random = new Random(); int age = random.nextInt(100); /获取一个Student对象,并将随机数年龄插入到对象属性中 Student studen

12、t = this.getStudent();/调用自定义的方法 student.setAge(age);/只能修改自己线程“信箱“中的对象 System.out.println(“thread “ + currentThreadName + “ first read age is:“ + student.getAge(); try Thread.sleep(500);catch (InterruptedException ex) ex.printStackTrace(); System.out.println(“thread “ + currentThreadName + “ second r

13、ead age is:“ + student.getAge(); ,该同就得同如果两个或两个以上的线程都修改同一对象(的属性),那么把执行修改的方法定义为被同步的,如果更新影响到了只读方法,那么该只读方法也要定义成同步的。不该同就不同不要滥用同步。多个线程如果访问的不是同一对象的同一属性,就不要将方法设置为synchronized的。顺水推舟每当一个方法释放某个对象的同步锁时,它应当调用notifyAll()来让等待队列中的其他线程有机会执行。,有借有还仔细查看每次调用wait()方法,都有相应的notify()/notifyAll()方法,且它们均作用于同一个对象。追根溯源wait()和no

14、tify()/notifyAll()是Object类方法,而不是Thread类的方法。,后台线程(守护线程) Daemon Thread,在后台运行的线程,为其他的线程提供服务 可以用setDaemon(boolean b)来把一个线程设置成后台线程 经常用于任务结束时的善后处理 典型的后台线程是定时器Timer线程 后台线程的优先级比其他线程的低 如果没有“用户线程”在运行,JVM将退出,守护线程将被自动终止,后台线程(守护线程) Daemon Thread,public class DaemonThread extends Threadpublic void run()while(true

15、)System.out.println(“Deamon Thread running.“);public static void main(Stringargs)DaemonThread dt = new DaemonThread();dt.setDaemon(true);dt.start();/主线程即将结束 ,Timer TimerTask,java.util.Timer Timer(boolean isDaemon) 创建一个新计时器,可以指定其相关的线程作为守护程序运行java.util.TimerTask public abstract class TimerTask extends

16、 Object implements Runnable,典型的后台线程Timer,public static void main(String args) /主线程开始Timer timer = new Timer(true);/如果没有设置为true,则会一直执行timer.schedule(new TimerTask() public void run() /TimerTask实现了Runnable接口Calendar c = Calendar.getInstance();int hour = c.get(Calendar.HOUR_OF_DAY);int minite = c.get(C

17、alendar.MINUTE);int second = c.get(Calendar.SECOND);System.out.println(hour + “:“ + minite + “:“ + second);, 0,1000);/后台线程启动try Thread.sleep(5000); catch (InterruptedException e) e.printStackTrace();/主线程终止后,后台线程会停下来 ,练习:定时器任务,在明天上午11:30分开始每隔一秒提醒(打印)一次:吃饭不积极,做人有问题. 注意:不要将Timer设置为后台线程,否则用户线程结束之后,会自动停止

18、.,用线程实现接口回调,创建线程时,给线程的构造方法传一个当前类的对象; 线程任务完成时应该用该对象调用某个方法,进行后续处理; Demo,用线程实现接口回调,为了更好的扩展性,线程的构造方法的形参应该声明成接口类型的,在调用构造方法时传入实现类的对象,在线程完成工作后用该引用调用接口中定义的方法(在实现类中做了重写)Demo,用线程实现接口回调,通常把一个匿名内部类的对象作为实参传递给线程类的构造方法,在匿名内部类中重写接口中定义的方法. Demo,线程 VS 进程 创建和启动线程的方式 实现Runnable接口 继承自Thread类 线程的状态转换 线程的调度和优先级 sleep,join

19、,yield synchronized线程同步 死锁问题 线程间的通信wait 、notify / notifyAll 生产者、消费者问题 ThreadLocal 线程局部变量 守护线程Timer,TimerTask 接口回调,25,1. 写一个线程安全的栈MyStack(相当于店员Clerk类),底层用LinkedList实现,提供进栈和出栈的方法,应用生产者-消费者模式。另外写两个线程类,分别实现生产者(Producer)和消费者(Consumer)。以及一个测试的场景类. 栈的大小是10个(最多能放10个元素)push(),pop() 1417.day24_t.ProConDemoTes

20、t.java 效果演示: 添加a1成功!集合中还有1个 删除a1成功!集合中还有0个 添加a2成功!集合中还有1个 删除a2成功!集合中还有0个 添加a3成功!集合中还有1个 添加a4成功!集合中还有2个,26,作业,2. 完成车票的售票系统HuoChePiaoDemo.java (1)由一个线程InitTickets去初始化车票(Tickets:属性count设置初始数量100张) (2)完成初始化车票后,调用CallBackSellTickets接口的sellAndReturnTickets方法; (3)在其重写方法中,创建多个售票线程SellTickets售票;创建多个线程ReturnTickets退票(退回的是当前最后发售的车票) 效果演示: 初始化车票已经完成 Thread-1已经售出第100张车票 Thread-2已经售出第99张车票 Thread-3已经退回第99张车票 Thread-4已经退回第100张车票 Thread-1已经售出第100张车票 Thread-2已经售出第99张车票 Thread-2已经售出第98张车票 Thread-3已经退回第98张车票 . .,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医学治疗 > 基础医学

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报