




已阅读5页,还剩18页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第22讲 Java高级编程(一),教学目标,理解多线程程序设计的基本思想 掌握多线程的实现和线程的同步与控制 理解Java网络编程的基本思想 掌握基于Socket的低层Java网络编程与基于UDP的Java网络编程,以及基于无连接的数据报通信编程 理解JDBC的基本思想 掌握数据源的建立和数据库的访问,多线程程序设计,支持多线程Java可以让不同的程序块同时运行,可以达到处理多任务的目的。 所谓的线程(thread)是指程序的运行流程,多线程的技术使单个程序内部也可以在同一时刻执行多个代码段,完成不同的任务,这种机制称为多线程。 Java语言利用多线程实现了一个异步的执行环境。例如,在一个网络应用程序里,可以在后台运行一个下载网络数据的线程,在前台则运行一个线程来显示当前下载的进度,以及一个用于处理用户输入数据的线程。 Java多线程机制是通过Java类包java.lang中的类Thread实现的,Thread类封装了对线程控制所必需的方法。,class ST extends Thread public ST(String str) super(str); public void run() String B = “起床“,“早饭“,“上班“,“下班“; String S = “备课“,“上课“,“布置作业“,“下课“; String Name = null; Name = getName(); for(int i = 0;i4;i+) if(Name.equals(“B“) System.out.println(Name+“:“+Bi); try sleep(long)(Math.random()*1000); catch(InterruptedException e) if(Name.equals(“S“) System.out.println(Name+“:“+Si); try sleep(long)(Math.random()*1000); catch(InterruptedException e) ,单线程实现示例,单线程实现示例(续),public class Ex12_1 public static void main(String args) ST s1 = new ST(“B“); ST s2 = new ST(“S“); s1.run(); s2.run(); ,运行结果: B:早饭 B:上班 B:下班 S:备课 S:上课 S:布置作业 S:下课,程序分析: try块中sleep()方法只是简单地告诉线程休息多少毫秒,其参数为休息时间。当这个时间过去后,线程即可继续执行。当某个线程睡眠时,sleep()并不占用系统资源,其他某一线程可继续工作。,多线程的实现,单线程的限制要运行s2.run()方法,一定要等到s1.run()运行完毕才行。 激活多个线程同时运行s1.run()、s2.run()方法使得上述结果交叉输出。 实现多线程的方法: 在类里激活线程 此类必须是扩展自Thread类,extends Thread 线程的处理必须编写在run()方法内。 run()方法是定义在Thread类中的一个方法。 使用接口实现多线程,多线程实现示例,class ST extends Thread public ST(String str) super(str); public void run() String B = “起床“,“早饭“,“上班“,“下班“; String S = “备课“,“上课“,“布置作业“,“下课“; String Name = null; Name = getName(); for(int i = 0;i4;i+) if(Name.equals(“B“) System.out.println(Name+“:“+Bi); try sleep(long)(Math.random()*1000); catch(InterruptedException e) if(Name.equals(“S“) System.out.println(Name+“:“+Si); try sleep(long)(Math.random()*1000); catch(InterruptedException e) ,多线程实现示例(续),public class Ex12_2 public static void main(String args) new ST(“B“).start(); new ST(“S“).start(); ,运行结果: 第一次运行 第二次运行 第三次运行 B:起床 B:起床 B:起床 S:备课 S:备课 S:备课 S:上课 B:早饭 S:上课 S:布置作业 S:上课 B:早饭 B:早饭 B:上班 B:上班 S:下课 S:布置作业 B:下班 B:上班 B:下班 S:布置作业 S:下班 S:下课 S:下课,程序分析: 程序中的main()方法中构 造了两个ST类的线程,一个称 为“B”线程“,另一个称为“S”线 程,并调用了start()方法来启 动这两个线程。这两个线程同时运行,并且同时显示输出,且这两个线程的输出次序是随机的。,使用接口实现多线程,如果类本身已经继承了某个父类,现在又要继承Thread类来创建线程,就违背了Java不支持多继承的原则,解决这个问题的方法是使用接口。 实现接口Runnable。Runnable接口里声明了抽象的run() 方法,把处理线程的程序代码放在run()里就可以创建线程了。 创建一个程序实现当前时间显示,要求每2秒显示1次,显示20次后程序退出。 分析:在Java的java.util包中有一个Date类,可以通过实例化一个Date对象得到当前时间。要求每两秒显示一次时间,线程是完成这个任务最好的角色。通过每两秒唤醒线程一次,并且就在这一瞬间显示出时间。还需设置一个循环控制输出次数。,使用接口实现多线程示例,import java.util.Date; public class Ex12_3 implements Runnable private Thread clock = null ;private Date nowtime = new Date(); public Ex12_3()clock = new Thread(this);clock.start(); public void run() while(true) nowtime = new Date(); System.out.println(nowtime); tryclock.sleep(2000); catch(InterruptedException ie) System.err.println(“Thread error: “ + ie); public static void main(String args) Ex12_3 time = new Ex12_3(); ,使用接口实现多线程示例(续),运行结果: Sat Feb 10 10:51:37 CST 2007 Sat Feb 10 10:51:39 CST 2007 Sat Feb 10 10:51:41 CST 2007 Sat Feb 10 10:51:43 CST 2007 Sat Feb 10 10:51:45 CST 2007 Sat Feb 10 10:51:47 CST 2007 Sat Feb 10 10:51:49 CST 2007 Sat Feb 10 10:51:51 CST 2007 Sat Feb 10 10:51:53 CST 2007 Sat Feb 10 10:51:55 CST 2007 Sat Feb 10 10:51:57 CST 2007 Sat Feb 10 10:51:59 CST 2007 Sat Feb 10 10:52:01 CST 2007 Sat Feb 10 10:52:03 CST 2007 Sat Feb 10 10:52:05 CST 2007 Sat Feb 10 10:52:07 CST 2007 Sat Feb 10 10:52:09 CST 2007 Sat Feb 10 10:52:11 CST 2007 Sat Feb 10 10:52:13 CST 2007 Sat Feb 10 10:52:15 CST 2007,程序分析: 通过Thread类的构造方法创建clock线程并进行初始化,同时将Ex12_3类的当前对象(this)作为参数。该参数将clock线程的run()方法与Ex12_3类实现runnable接口的run()方法联系在一起,因此,当线程启动后,Java类的run()方法就开始执行。,多线程同步示例,class Countmoney private static int sum=0; public static void add(int n) int t = sum; t = t + n; try Thread.sleep(int)(1000*Math.random(); catch(InterruptedException e) sum = t; System.out.println(“sum=“+sum); class Cperson extends Thread public void run() for(int i = 1;i=3;i+) Countmoney.add(100); ,public class Ex12_4 public static void main(String args) Cperson c1 = new Cperson(); Cperson c2 = new Cperson(); c1.start(); c2.start(); ,运行结果: sum=100 sum=200 sum=300 sum=100 sum=200 sum=300,多线程同步示例,程序分析: 输出结果不正确。其错误原因在于两个线程在各自run()方法还没结束前,另一个线程已开始激活,因此造成计算上的错误。 要更正这个错误,只要设置c1线程处理完之后,接着处理c2线程就可以了。在aad()方法之前加上synchronized关键字,使其成为同步方法。,public synchronized static void add(int n) class Cperson extends Thread public void run() for(int i = 1;i=3;i+) Countmoney.add(100); ,为了避免资源冲突,Java使用关键字synchronized使方法通信同步,在同一时间内,一个方法只能有一个线程运行。 在本例中,可以学到同步处理的重要性。如有多个线程共享一个变量时,特别要注意它们之间的访问顺序,否则一个线程未处理完某个方法时,另一个线程又进来,就有可能发生错误。,实现多线程同步 synchronized,线程的四种状态,每一个线程,一般有四种状态:创建、运行、阻塞与消亡。这四种状态均可通过Thread类所提供的方法来控制。线程状态的转移与方法之间的关系如图12-1所示。 线程在产生时便进入创建状态。即new Thread()创建对象时,线程所处的便是这个状态,但此时系统并不会分配资源,直到用start()方法激活线程时才会分配。 当start()方法激活线程时,线程进入可运行的状态。此时最先抢到CPU资源的线程先开始运行start()方法,其余的线程在队列中等待机会争取CPU的资源,一旦争取到就开始运行。,线程状态转换图,图12-1 线程状态的转移与方法之间的关系,线程的四种状态的转换过程,当发生下列事件之一时,线程就进入阻塞状态。 1该线程调用对象的wait()方法; 2该线程本身调用sleep()方法。sleep(long millis)可用来设置睡眠的时间。 3该线程和另一个线程join()在一起时。当某一线程调用join()时,则其他尚未激活的线程或程序代码会等到该线程结束后才会开始运行。 当线程被阻塞后,便停止run()方法的运行,直到被阻塞的原因不存在后,线程回到可运行状态,继续排队争取CPU的资源。,线程的状态转换,线程被阻塞情形消失的原因有下列几点: 1如果线程是由调用对象的wait()方法所阻塞,则该对象的notify()方法被调用时可解除阻塞。notify()方法用来“通知”被wait()阻塞的线程开始运行。 2线程进入睡眠状态,但指定的睡眠时间到了。 当线程的run()方法结束,或是线程调用它的stop()时,则线程进入消亡的状态。 利用上述方法可以完成线程间的通信以及线程状态之间的转换,下面举例说明通过wait()、notify()来达到线程间的通信和状态的转换。,线程间通信示例,例12_5 线程间通信的示例。本例模拟两个银行之间的转帐业务,当A银行转帐给B银行后,暂停转帐,通知B银行转帐给A银行,转帐金额随机确定,源代码如下。,import java.awt.*; import java.awt.event.*; public class Ex12_5 extends Frame protected static final String NAMES = “A“,“B“; private int accounts = 1000,1000; private TextArea info = new TextArea(5,40); private TextArea status = new TextArea(5,40);,public Ex12_5() super(“Ex12_5“);setLayout(new GridLayout(2,1); add(makePanel(info,“Accounts“); add(makePanel(status,“Threads“); validate();pack();setVisible(true); Ex12_5Thread A = new Ex12_5Thread(0,this,status); Ex12_5Thread B = new Ex12_5Thread(1,this,status); addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent we) System.exit(0); );,线程间通信示例(续),public synchronized void transfer(int from,int into,int amount) info.append(“nAccount A: $“ + accounts0); info.append(“tAccount B: $“ + accounts1); info.append(“n= $“ + amount + “ from “ + NAMESfrom + “ to “ + NAMESinto); while(accountsfrom amount) trywait();catch(InterruptedException ie)System.err.println(“Error: “ + ie); accountsfrom -= amount;accountsinto +=amount;notify(); private Panel makePanel(TextArea text,String title) Panel p = new Panel(); p.setLayout(new BorderLayout(); p.add(“North“,newLabel(title); p.add(“Center“,text);return p; public static void main(String args) Ex12_5 bank = new Ex12_5(); public static void main(String args) Ex12_5 bank = new Ex12_5(); ,线程间通信示例(续),class Ex12_5Thread extends Thread private Ex12_5 bank; private int id; private TextArea display; public Ex12_5Thread(i
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年智能交通系统专业资格考试试卷及答案
- 2025年职业生涯规划与发展考试试题及答案
- 2025年特殊教育服务与支持考试试题及答案
- 2025年广告与市场传播专业考生模拟考试试题及答案
- 2025年互联网金融专业试卷及答案
- 2025年公共关系与危机管理考试题及答案
- 2025年法律硕士考试试题及答案
- 2025年护士资格认证考试试题及答案
- 养殖合同协议书找谁弄
- 2025年多协议通信适配器合作协议书
- 剑9阅读真题原文1-William-Henry-Perkin
- 煤矿供电系统简介
- 家庭教育方式综合测验
- 律师会见笔录范本
- 浙教版科学电学基础知识总结
- T/CEC 164-2018 火力发电厂智能化技术导则_(高清-最新版)
- 抹机水MSDS 安全资料表
- 医院感染管理组织框架
- 完整版混凝土结构设计原理课程设计——单向板肋梁楼盖设计计算书
- 特殊平行四边形课件
- 尾矿库基础知识(金属非金属矿山尾矿库安全技术中心)
评论
0/150
提交评论