《Java多线程编程实例讲解.ppt》由会员分享,可在线阅读,更多相关《Java多线程编程实例讲解.ppt(16页珍藏版)》请在三一办公上搜索。
1、Java程序设计,重庆交大,2023/7/6,13.Java多线程编程实例讲解,13.1 多线程应用实例计算素数13.2 多线程应用实例计数程序13.3 课后作业,2023/7/6,13.1 多线程应用实例计算素数,本节给出一个用Java语言编写的比较经典的多线程应用程序(2,P122)。该Java程序实现的功能是:计算并输出第N个素数,N值可能很大,比如10000;可同时计算若干个素数,比如同时计算并输出第10000、10001、10002个素数。本程序采用多线程技术实现:由于N值很大时,计算第N个素数的计算量还是比较大;特别地,要求可以同时计算若干个素数,这样把计算并输出第N个素数的功能用
2、线程实现,如果要同时计算若干个素数,则计算每个素数单独开启一个线程。计算素数的功能用PrimeFinder类实现。程序清单:chapter13PrimeFinder.java。,2023/7/6,13.1 多线程应用实例计算素数,本实例采用第2种方式(实现runnable接口创建线程类)来创建并启动线程。,package chapter13;public class PrimeFinder implements Runnable public long target;/成员变量:第N个素数当中的N值 public long prime;/就是所找到的第N个素数 public boolean f
3、inished=false;/标志着当前线程是否结束 private Thread runner;/就是当前创建并启动的线程对象/构造方法:参数inTarget,接收到的需要查找的第N个素数当中的N值/【注意】这个N值要以构造函数参数的形式传进来,/且通常要定义相应的实例变量 PrimeFinder(long inTarget)target=inTarget;if(runner=null)runner=new Thread(this);runner.start();,public void run()/线程的执行体 long numPrimes=0;/计数,当前找到的是第几个素数 long c
4、andidate=2;/candidate,每一个候选的素数 while(numPrimes target)if(isPrime(candidate)numPrimes+;prime=candidate;candidate+;finished=true;boolean isPrime(long checkNumber)/判断checkNumber是否为素数 double root=Math.sqrt(checkNumber);for(int i=2;i=root;i+)if(checkNumber%i=0)return false;return true;,【注意】与第12章例子不同的时,线程
5、的创建及启动是在Runnable实现类的构造函数中实现的。,2023/7/6,13.1 多线程应用实例计算素数,以下PrimeThreads类是使用PrimeFinder类的应用程序。程序清单:chapter13PrimeThreads.java。应用程序PrimeThreads可以同时查找多个素数。用户可通过命令行参数指定要查找哪几个素数。要在NetBeans中设置命令行参数,详见文档:Java相关开发工具经验汇总.doc。,2023/7/6,13.1 多线程应用实例计算素数,package chapter13;public class PrimeThreads public static
6、void main(String arguments)PrimeThreads pt=new PrimeThreads(arguments);/构造函数:从参数数组中读取每个整数并为每个整数创建并启动一个线程 public PrimeThreads(String arguments)PrimeFinder finder=new PrimeFinderarguments.length;for(int i=0;i arguments.length;i+)try long count=Long.parseLong(argumentsi);finderi=new PrimeFinder(count);
7、System.out.println(Looking for prime+count);catch(NumberFormatException nfe)System.out.println(Error:+nfe.getMessage();,boolean complete=false;/判断开启的每个线程是否结束 while(!complete)complete=true;for(int j=0;j finder.length;j+)if(finderj=null)continue;if(!finderj.finished)complete=false;else displayResult(f
8、inderj);finderj=null;/输出找到的素数 private void displayResult(PrimeFinder finder)System.out.println(Prime+finder.target+is+finder.prime);,2023/7/6,13.1 多线程应用实例计算素数,使用命令行参数“10000 10001 10002”运行该程序,其输出可能为:Looking for prime 10000Looking for prime 10001Looking for prime 10002Prime 10000 is 104729Prime 10001
9、is 104743Prime 10002 is 104759,2023/7/6,13.1 多线程应用实例计算素数,线程结束的顺序是不确定的(特别是上述三个线程所花费的时间很接近),因此输出也可能为:Looking for prime 10000Looking for prime 10001Looking for prime 10002Prime 10002 is 104759Prime 10000 is 104729Prime 10001 is 104743以上输出表明,寻找第10002个素数的线程比寻找第10000个素数的线程先结束。,2023/7/6,13.2 多线程应用实例计数程序13.
10、2.1 未使用多线程技术的计数程序,程序清单:chapter13Counter.java。以上程序的运行界面如下图所示。当单击“Start”按钮时,程序调用addCounter方法,并在文本框中开始计数,从0到99。每次计数后调用Thread类的静态方法sleep使得当前线程暂停50毫秒,此方法的调用并不会新建线程,而是暂停当前线程的活动。,2023/7/6,13.2 多线程应用实例计数程序13.2.1 未使用多线程技术的计数程序,如果希望在计数过程中停止程序运行,似乎单击“Close”按钮就可以停止计数并关闭窗口。但是,实际上却发现“Close”按钮的单击“似乎”不起作用,计数依然在继续;当
11、计数到99,没有单击“Close”按钮,程序却退出了。原因何在呢?这是因为该程序是单线程运行的,一旦某个任务启动了,必须要等到这个任务完成才能进行其他任务的执行。因此当计数开始后,程序不会对其他操作有所反应,而是必须执行完100次循环,然后才能响应“Close”按钮的单击操作,关闭程序。,2023/7/6,13.2 多线程应用实例计数程序13.2.1 未使用多线程技术的计数程序,可以看出,上面的单线程程序缺乏交互性。如果希望在计数的同时,程序也能响应其他操作,这需要通过线程机制来实现。在线程机制中,CPU可以为每个线程都分配自己的一部分时间。每个线程都“感觉”自己好像拥有整个CPU,但CPU的
12、计算时间实际却是在所有线程间分摊的。,2023/7/6,13.2 多线程应用实例计数程序13.2.2 实现一个计数线程的计数程序,实现线程的前提是对程序子任务的划分。对于上面的例子,现在把计数程序分为两个线程:一个用于计数,一个用于事件调度(即主线程)。程序清单:chapter13.test1CounterThread.java。以上程序的运行界面如下图所示。,2023/7/6,13.2 多线程应用实例计数程序13.2.2 实现一个计数线程的计数程序,从上面的程序可以看出,创建线程的方法很简单:将需要独立运行的子任务代码放到从Thread类派生类的run方法中。然后在主线程中原先调用该子任务的
13、地方先创建一个该线程类的实例,再调用线程类的start方法启动线程。新线程只能由start方法启动,然后才能执行run方法。现在,在计数过程中,当单击“Close”按钮后,程序立刻会退出,和我们所设想的一样。,2023/7/6,13.2 多线程应用实例计数程序13.2.3 实现多个计数线程的计数程序,更深入一步,我们希望把“Start”按钮换成“Add”按钮,每次点击“Add”按钮,增加一个文本框,同时在文本框中启动一个新的计数。这需要创建多个线程。程序清单:chapter13.test2CounterMultiThread.java。,2023/7/6,13.2 多线程应用实例计数程序13.2.3 实现多个计数线程的计数程序,以上程序的运行界面如下图所示。每次单击“Add”按钮,在窗口上新增一个文本框,该程序最多允许添加16个文本框。每个文本框都执行自己的计数功能。,2023/7/6,13.3 课后作业,自由落下和水平抛出的小球。编写一个Java GUI应用程序,采用Java多线程技术,模拟自由落体和平抛运动:一个球自由落下,另一个球水平抛出。(自由落体物理公式:h=g*t2/2;平抛运动物理公式:h=g*t2/2,x=26*t),