Java14第十二章-多线程

上传人:伴*** 文档编号:243097972 上传时间:2024-09-15 格式:PPT 页数:41 大小:273.50KB
返回 下载 相关 举报
Java14第十二章-多线程_第1页
第1页 / 共41页
Java14第十二章-多线程_第2页
第2页 / 共41页
Java14第十二章-多线程_第3页
第3页 / 共41页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,二级,三级,四级,五级,*,*,安卓越科技(北京)有限公司,41,第十二章,多线程,回顾与作业点评,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,= 20) ,try ,/,产品已满,请稍候再生产,wait();, catch (,InterruptedException,e) ,e.printStackTrace,();, else ,product+;,System.out.println,(,生产者生产第, + product + ,个产品,);,/,通知等待区的消费者可以取产品了,notifyAll,();,/,消费者从店员处取产品,public synchronized void,getProduct,() ,if (,this.product,= 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) ,System.out.println(Complete,.);, else ,synchronized (res2) ,System.out.println,(,锁定资源,2,,等待资源,1*);,try ,Thread.sleep(1000);, catch (,InterruptedException,e) ,synchronized (res1) ,System.out.println(Complete,.);,12.5,集合类的同步问题,:,集合类有的是线程同步(也叫线程安全)的,,有的不是。,12.5.1,使用,sysnchronized,同步块,12.5.2,使用集合工具类同步化集合类对象,:Collections,的,synchronizedSet,(),synchronizedList,(),synchronizedMap,(),12.5.3,使用,JDK5,后提供的并发集合类,CopyOnWriteArrayList,12.6,用,Timer,类调度任务,: Timer,类代表一个计时器,与每个,Timer,对象相应,的是单个后台线程,用于顺序地执行所有计时器任务。,import,java.io.IOException,;,import,java.util.Timer,;,import,java.util.TimerTask,;,public class,TimerTest,public static void,main(String,args,) ,Timer,timer,= new Timer();,/,立即开始执行指定任务,并间隔,1000,毫秒就重复执行一次,/,timer.schedule(new,MyTask,(), 0, 1000);,timer.scheduleAtFixedRate(new,MyTask,(), 0, 1000);,while (true) ,try ,int,ch,=,System.in.read,();,if (,ch,= q) ,timer.cancel,(); /,使用这个方法退出任务,break;, catch (,IOException,e) ,e.printStackTrace,();,class,MyTask,extends,TimerTask,public void run() ,System.out.println,(,起床了,.);,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 小学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!