




已阅读5页,还剩36页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第十二章,多线程,回顾与作业点评,JAVA集合框架 List Map Set接口 容器的泛型操作 Comparable接口 equals和 hashCode方法的理解,本章任务,掌握线程的创建和启动 掌握线程的状态及转换 掌握线程的调度和优先级 掌握 线程的同步 掌握集合类的同步问题 Timer类的调度任务,知识要点,线程的创建和启动 线程的状态及转换 线程的调度和优先级 线程的同步 集合类的同步问题 Timer类的调度任务,12.1 理解线程 线程是程序中一个单一的顺序控制流程 12.1.1 什么是多线程 在单个程序中同时运行多个线程完成不同的工作,称为多线程. 12.1.2 进程和线程的区别 1.进程(process) 进程是指每个独立程序在计算机上的一次执行活动 2.线程(thread) 线程就是一个程序内部的一条执行路径,3.线程和进程的区别,12.1.3 线程的创建和启动 1.创建新线程 1)定义实现java.lang.Runnable接口的类 /* 实现自java.lang.Runnable来创建一个打算用线程来执行的类 */ public class MyRunner implements Runnable public void run() / 要在线程中执行的代码 for (int i = 0; i 100; i+) System.out.println(“MyRunner:“ + i); ,2)将类定义为Thread类的子类并重写run()方法 /* 继承自java.lang.Thread类来创建一个线程类 */ public class MyTread extends Thread public void run() / 要在线程中执行的代码 for (int i = 0; i 100; i+) System.out.println(“MyThread:“ + i); 2.启动线程:调用线程实例的start()方法,class MyTread extends Thread public void run() / 要在线程中执行的代码 for (int i = 0; i 100; i+) System.out.println(“MyThread:“ + i); ,/* 创建和启动多个线程 */ public class FirstThreadTest public static void main(String args) System.out.println(“主线程开始执行“); Thread thread1 = new Thread(new MyRunner(); thread1.start(); System.out.println(“启动一个新线程(thread1).“); Thread thread2 = new MyTread(); thread2.start(); System.out.println(“启动一个新线程(thread2).“); System.out.println(“主线程执行完毕“); ,12.1.4Thread类介绍,12.1.5为什么需要多线程 1.提高应用程序响应 2.提高CPU的利用率 3.改善程序结构 12.1.6 线程分类 *用户线程:java虚拟机在他所有非守护线程都已经离开后自动离开 *守护线程:是为其他线程提供服务的一种线程,是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去,12.2 线程的生命周期 12.2.1 线程的状态及转换 *NEW:新建状态,尚未启动的线程处于这种状态 *RUNNABLE:可运行状态,在JAVA虚拟机中执行的线程处于这种状态 *BLOCKED:阻塞状态,受阻塞并等待某个监视器锁的线程处于这种状态 *WAITING:等待状态,无限期地等待另一个线程来执行某一特定操作的线程处于这种状态 *TIMED_WAITING:超时等待状态,等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态 *TERMINATED:终止状态,已退出的线程处于这种状态,1.新线程 2.可运行线程 3.被阻塞和等待状态下的线程 4.被终止的线程 12.2.2 线程睡眠:在线程中调用sleep()方法会使当前线程进入睡眠状态,相应时间过后会苏醒,重新进入可运行状态。,new,runnable,terminated,blocked,waiting,timed waiting,Start(),run(),获取了对象锁,释放对象锁,wait() join(),notify() notifyAll(),wait() join() sleep(),超时过期,线程的状态及转换图:,public class ThreadSleepTest public static void main(String args) System.out.println(“主线程开始执行“); Thread thread1 = new Thread(new SleepRunner(); thread1.start(); System.out.println(“启动一个新线程(thread1).“); Thread thread2 = new Thread(new NormalRunner(); thread2.start(); System.out.println(“启动一个新线程(thread2).“); System.out.println(“主线程执行完毕“); class SleepRunner implements Runnable public void run() ,线程睡眠:在线程体中调用sleep()方法会使当前线程进入睡眠状态,苏醒后重新进入可运行状态。,try Thread.sleep(100); /线程睡眠100毫秒 catch (InterruptedException e) e.printStackTrace(); / 要在线程中执行的代码 for (int i = 0; i 100; i+) System.out.println(“SleepRunner:“ + i); class NormalRunner implements Runnable public void run() / 要在线程中执行的代码 for (int i = 0; i 100; i+) System.out.println(“NormalRunner:“ + i); ,线程睡眠:,12.2.3 线程让步:Thread.yield()方法会暂停当前正在执行的线程对象,把执行机会让给相同或更高优先级的线程。,public class ThreadYieldTest public static void main(String args) /获取当前线程的名称 System.out.println(Thread.currentThread().getName(); Thread thread1 = new Thread(new YieldThread(); thread1.start(); Thread thread2 = new Thread(new YieldThread(); thread2.start(); ,class YieldThread implements Runnable public void run() for(int i = 0; i 100; i+) System.out.println(Thread.currentThread().getName()+ “:“ + i); if(i % 10 = 0) /当i可以被10整除时,当前线程让步给其它线程 Thread.yield(); /线程让步的方法 ,12.2.4 线程的加入:join()方法可使两个交叉执行 的线程变成顺序执行。,public class ThreadJoinTest public static void main(String args) Thread thread1 = new Thread(new MyThread3(); thread1.start(); /主线程中执行for循环 for (int i = 1; i = 50; i+) System.out.println(Thread.currentThread().getName() + “:“ + i); if (i = 30) try thread1.join(); /把子线程加入到主线程中执行 catch (InterruptedException e) e.printStackTrace(); ,class MyThread3 implements Runnable public void run() for (int i = 1; i = 20; i+) System.out.println(Thread.currentThread().getName() + “:“ + i); try Thread.sleep(10); catch (InterruptedException e) e.printStackTrace(); ,12.3 线程的调度和优先级:线程的调度是让JVM对多个线程进行系统级的协调,以避免因争夺资源引起的死机。JAVA定义了线程的优先级,数字越大级别越高。,public class ThreadPriorityTest public static void main(String args) Thread t0 = new Thread(new R(); /第一个子线程 Thread t1 = new Thread(new R(); /第二个子线程 t1.setPriority(Thread.MAX_PRIORITY); /把第二个子线程的优先级设置为最高 t0.start(); t1.start(); ,class R implements Runnable public void run() for (int i = 0; i 100; i+) System.out.println(Thread.currentThread().getName() + “: “ + i); ,12.4 线程的同步:为避免多个线程同时访问一个共享数据,需要对访问进行同步。,/* 奥运门票销售系统 */ public class TicketOfficeTest public static void main(String args) TicketOffice off = new TicketOffice(); /要多线程运行的售票系统 Thread t1 = new Thread(off); t1.setName(“售票点1“); /设置线程名 t1.start(); Thread t2 = new Thread(off); t2.setName(“售票点2“); t2.start(); Thread t3 = new Thread(off); t3.setName(“售票点3“); t3.start();,Thread t4 = new Thread(off); t4.setName(“售票点4“); t4.start(); Thread t5 = new Thread(off); t5.setName(“售票点5“); t5.start(); class TicketOffice implements Runnable private int tickets = 0; /门票计数器成员变量 public void run() /线程体 boolean flag = true; /是否还有票可买-局部变量 while (flag) flag = sell(); /售票 ,private Lock lock = new ReentrantLock(); public boolean sell() /售票方法,返回值表示是否还有票可卖 boolean flag = true; / synchronized (this) /同步操作到共享数据的代码块 lock.lock(); if(tickets 100) tickets = tickets + 1; /更改票数 System.out.println(Thread.currentThread().getName()+ “:卖出第“ + tickets + “张票“); else flag = false; lock.unlock(); / try Thread.sleep(15); /为了增大出错的几率,让线程睡眠15毫秒 catch (InterruptedException e) e.printStackTrace(); return flag; ,12.4.1 线程同步的方法 1.同步方法:synchronized放在方法声明中,表示整个方法为同步方法。 Public synchronized boolean sell() /售票方法,返回值表示是否还有票可卖 boolean flag = true; / synchronized (this) /同步操作到共享数据的代码块 lock.lock(); if(tickets 100) tickets = tickets + 1; /更改票数 System.out.println(Thread.currentThread().getName()+ “:卖出第“ + tickets + “张票“); else flag = false; lock.unlock(); / ,try Thread.sleep(15); /为了增大出错 的几率,让线程睡眠15毫秒 catch (InterruptedException e) e.printStackTrace(); return flag; ,2 同步代码块:把共享数据相关语句放在中,然后用synchronized修饰。,public boolean sell() /售票方法,返回值表示是否还有票可卖 boolean flag = true; synchronized (this) /同步操作到共享数据的代码块 lock.lock(); if(tickets 100) tickets = tickets + 1; /更改票数 System.out.println(Thread.currentThread().getName()+ “:卖出第“ + tickets + “张票“); else flag = false; ,lock.unlock(); try Thread.sleep(15); /为了增大出错的几率,让线程睡眠15毫秒 catch (InterruptedException e) e.printStackTrace(); return flag; ,12.4.2对象锁:JVM为每个线程都关联一个锁,代表任何时候只允许一个线程拥有的特权。Java virtual machine,Private Lock lock=new ReentrantLock(); public boolean sell() /售票方法,返回值表示是否还有票可卖 boolean flag = true; / synchronized (this) /同步操作到共享数据的代码块 lock.lock(); if(tickets 100) tickets = tickets + 1; /更改票数 System.out.println(Thread.currentThread().getName()+ “:卖出第“ + tickets + “张票“); else flag = false; ,lock.unlock(); / try Thread.sleep(15); /为了增大出错的几率,让线程睡眠15毫秒 catch (InterruptedException e) e.printStackTrace(); return flag; ,12.4.3 wait 和notify方法: 当wait方法被调用时,当前线程被中断运行,并且放弃该对象的锁。当另外的线程执行了某个对象的notify方法后,会唤醒在此对象等待池中的某个线程使之成为可运行的线程。,/生产者消费者问题 public class ProductTest public static void main(String args) Clerk clerk = new Clerk(); / 生产者线程 Thread producerThread = new Thread(new Producer(clerk); / 消费者线程 Thread consumerThread = new Thread(new Consumer(clerk); producerThread.start(); consumerThread.start(); ,/ 店员 class Clerk / 默认为0个产品 private int product = 0; / 生产者生产出来的产品交给店员 public synchronized void addProduct() if (duct = 20) try / 产品已满,请稍候再生产 wait(); catch (InterruptedException e) e.printStackTrace(); else product+; System.out.println(“生产者生产第“ + product + “个产品“); / 通知等待区的消费者可以取产品了 notifyAll(); ,/ 消费者从店员处取产品 public synchronized void getProduct() if (duct = 0) try / 缺货,请稍候再取 wait(); catch (InterruptedException e) e.printStackTrace(); else System.out.println(“消费者取走了第“ + product + “个产品“); product-; / 通知等待区的生产者可以生产产品了 notifyAll(); ,class Producer implements Runnable private Clerk clerk; public Producer(Clerk clerk) this.clerk = clerk; public void run() System.out.println(“生产者开始生产产品“); while (true) try Thread.sleep(int) (Math.random() * 10) * 100); catch (InterruptedException e) e.printStackTrace(); / 生产产品 clerk.addProduct(); ,class Consumer implements Runnable private Clerk clerk; public Consumer(Clerk clerk) this.clerk = clerk; public void run() System.out.println(“消费者开始取走产品“); while (true) try Thread.sleep(int) (Math.random() * 10) * 100); catch (InterruptedException e) e.printStackTrace(); / 取产品 clerk.getProduct(); ,12.4.4 死锁:两个线程都在等待自己所需要的资源,而这些资源被另外的线程锁住,程序就卡住了,从而形成死锁。,public class DeadLockTest implements Runnable public boolean flag = true; private static Object res1 = new Object(); /资源1 private static Object res2 = new Object(); /资源2 public void run() if (flag) /* 锁定资源res1 */ synchronized (res1) System.out.println(“锁定资源1,等待资源2.“); try Thread.sleep(1000); catch (InterruptedException e) ,12.4.4 死锁:两个线程都在等待自己所需要的资源,而这些资源被另外的线程锁住,程序就卡住了,从而形成死锁。,synchronized (res2) Sys
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑施工材料采购及质量保证措施
- 施工单位机械设备协作配合措施
- 中职学校学生综合素质提升措施
- 餐饮连锁疫情预防控制工作措施
- 台湾省2025年公路造价师《理论与法规》合同的分类模拟试题
- 小学三年级数学学困生辅导措施
- 农业物联网技术应用与服务平台建设合同
- 高空作业车使用前安全措施
- 影视行业域名购买合同范文
- 施工扬尘监测与控制措施
- 五年级体育课教案全集
- 2025年注册测绘师测绘综合能力的真题卷(附答案)
- 项目城市轨道交通风险管理与安全评估刘连珂
- 道路施工机械设备安全知识培训
- 幼儿教育幼儿园安全知识教育试题
- AI在护理查房中的应用
- 哮喘患儿自我管理指导
- 证券行业智能化投资组合管理方案
- 银行员工消保知识培训
- 地理与劳动教育
- 第5课 甲午中日战争与列强瓜分中国狂潮 公开课一等奖创新教学设计
评论
0/150
提交评论