Java程序设计-第6章线程_第1页
Java程序设计-第6章线程_第2页
Java程序设计-第6章线程_第3页
Java程序设计-第6章线程_第4页
Java程序设计-第6章线程_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java的多线程

目录和要求

Java程序通过流控制来执行程序流,程序中单个顺序的流控制称为线程,多线程则指的是在单个程序中可以同时运行多个不同的线程,执行不同的任务。多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行。线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与进程不同的是,系统在产生一个线程,或者在各个线程之间切换时,负担要比进程小的多,正因如此,线程被称为轻负荷进程(light-weightprocess)。一个进程中可以包含多个线程。

学时:1学时Java的多线程讲义1多线程的概述

2多线程的实现方法与控制3多线程的互斥

4多线程的同步

5多线程的应用

6总结多线程的概念

线程是程序中的一条执行路径。多线程是指程序中包含多条执行路径。在一个程序中可以同时运行多个不同的线程来执行不同的任务,即允许单个程序创建多个并行执行的线程来完成各自的任务。浏览器程序就是一个多线程的例子,在浏览器中可以在下载Java小程序或图像的同时滚动页面,在访问新页面时,播放动画和声音,打印文件等。Java对多线程的支持

Java语言里,线程表现为线程类。Thread线程类封装了所有需要的线程操作控制。在线程对象里有很多方法来控制一个线程是否运行,睡眠,挂起或停止。线程类是控制线程行为的唯一的手段。一旦一个Java程序启动后,就已经有一个线程在运行。可通过调用Thread.currentThread方法来查看当前运行的是哪一个线程。多线程的概述下面是一些常用线程类的方法。(1)类方法currentThread():返回正在运行的Thread对象。yield():停止运行当前线程,将CPU控制权主动移交到下一个可运行线程。sleep(intn):让当前线程睡眠n毫秒,n毫秒后,线程可以再次运行。(2)实例(对象)方法start():为本线程建立一个执行环境,然后调用本线程的run()方法。run():在其中书写运行本线程的将要执行的代码,也是Runnable接口的唯一方法。当一个线程初始化后,由start()方法来调用它,一旦run()方法返回,本线程也就终止了。

stop():让某线程马上终止,系统将删除本线程的执行环境。suspend():将线程挂起,暂停运行,但系统不破坏线程的执行环境,可以用resume()来恢复本线程的执行。resume():恢复被挂起的线程进入可运行状态。setPriority(intp):给线程设置优先级1<=p<=10。getPriority():返回线程的优先级。setName(Stringname):赋予线程一个名字name。getName():取得由setName()方法设置的线程名字的字符串。wait(longtimeout):停止当前线程,直到另外的线程对这个对象使用notify()或notifyAll()方法。notify()或notifyAll():唤醒指定对象的一个或所有线程。线程的状态和生命周期一个线程从创建、启动到终止期间的任何时刻,总是处于下面五个状态中的某个状态。1.创建状态

用new运算符创建一个Thread类或子类的实例对象时,形成的新线程就进入创建状态,但此时还未对这个线程分配任何资源,没有真正执行它。2.可运行状态在创建线程后,若要执行它,系统要对这个线程进行登记,并为它分配系统资源,这些工作由start()启动方法来完成。线程启动后,将进入线程队列排队等待CPU时间片,成为可运行状态(或称为就绪状态)。此时线程已经具备了运行的条件,一旦它获得CPU等资源时,就可以脱离开创建它的主线程而独立运行。3.运行状态当可运行状态的线程被调度并获得CPU等资源时,便进入运行状态。4.阻塞状态由于人为或系统的原因,线程必须停止运行,以后还可以恢复运行的状态称为阻塞状态。发生以下几种情况之一后,线程进入阻塞状态。(1)调用了该线程的sleep()休眠方法。(2)该线程正在等待I/O操作完成。(3)调用了wait()等待方法。(4)调用了suspend()挂起方法。5.终止状态运行run()方法完成后或调用stop()或destroy()方法就进入线程的终止态(或称为死亡状态)。处于这种状态的线程不具有继续运行的能力。线程的调度和优先级处于可运行状态的线程进入线程队列排队等待CPU等资源时,同一时刻在队列中的线程可能有多个,它们完成各自任务的轻重缓急程度是不同的。为了体现上述差别,多线程系统会给每个线程自动分配一个线程的优先级。任务较重要或紧急的线程,分配较高的优先级,在可运行态的线程队列中就往前排;否则,就分配较低的优先级。优先级低的线程只能等到优先级高的线程执行完后才被执行。对于优先级相同的线程,则遵循队列的“先进先出”原则,即先到的线程先获得系统资源来运行。在Java语言中,对一个新建的线程,系统会分配一个缺省的线程优先级:继承创建这个线程的主线程的优先级(一般为普通优先级)。Thread类也提供了方法setPriority()来修改线程的优先级。该方法的参数一般可用Thread类的优先级静态常量:

PRIORITY.NORM_PRIORITY普通优先级(5)

PRIORITY.MIN_PRIORITY最低优先级(1)

PRIORITY.MAX_PRIORITY最高优先级(10)当一个在可运行状态队列中排队的线程被分配到CPU等资源而进入运行状态后,这个线程就称为是被“调度”或被线程调度管理器选中了。线程调度管理器负责管理线程排队和CPU等资源在线程间的分配。多线程的实现方法与控制可以通过继承Thread类或实现Runnable接口这两种途径来构造自己的run()方法。

多线程的实现方法1.继承Thread类可通过继承Thread类并重写其中的run()方法来定义线程体以实现线程的具体行为,然后创建该子类的对象以创建线程。在继承Thread类的子类ThreadSubclassName中重写run()方法来定义线程体的一般格式为:

publicclassThreadSubclassNameextendsThread{publicThreadSubclassName(){.....//编写子类的构造方法,可缺省

}

publicvoidrun(){.....//编写自己的线程代码

}}用定义的线程子类ThreadSubclassName创建线程对象的一般格式为:

ThreadSubclassName

ThreadObject=newThreadSubclassName();然后,就可启动该线程对象表示的线程:

ThreadObject.start();//启动线程2.实现Runnable接口编写多线程程序的另一种的方法是实现Runnable接口。在一个类中实现Runnable接口(以后称实现Runnable接口的类为Runnable类),并在该类中定义run()方法,然后用带有Runnable参数的Thread类构造方法创建线程。创建线程对象可用下面的两个步骤来完成:(1)生成Runnable类ClassName的对象

ClassName

RunnableObject=newClassName();(2)用带有Runnable参数的Thread类构造方法创建线程对象。新创建的线程的指针将指向Runnable类的实例。用该Runnable类的实例为线程提供run()方法---线程体。

ThreadThreadObject=newThread(RunnableObject);然后,就可启动线程对象ThreadObject表示的线程:ThreadObject.start();在Thread类中带有Runnable接口的构造方法有:publicThread(Runnable

target);publicThread(Runnable

target,String

name);publicThread(String

name);publicThread(ThreadGroup

group,Runnable

target);publicThread(ThreadGroup

group,Runnable

target,

String

name);其中,参数Runnable

target表示该线程执行时运行target的run()方法,String

name以指定名字构造线程,ThreadGroup

group表示创建线程组。线程的建立举例publicclassMyThreadextendsThread{publicMyThread(Stringname){

super(name);}publicvoidrun(){

for(inti=0;i<3;i++){

System.out.println(getName()+"isrunning");try{

sleep((long)(Math.random()*1000));}catch(InterruptedExceptione){

System.out.println(e);}}

System.out.println(getName()+"hasstopped.");}publicstaticvoidmain(String[]args){

MyThreadt1=newMyThread("Thread1");

MyThreadt2=newMyThread("Thread2");t1.start();t2.start();}}importjavax.swing.*;publicclassMyThread1extendsJFrameimplementsRunnable{privateJTextArea

textArea=newJTextArea();publicMyThread1(){

setTitle("TestMultithread");

add(textArea);setSize(300,200);

setVisible(true);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}publicvoidrun(){

for(inti=0;i<3;i++){

textArea.append(Thread.currentThread().getName()+"isrunning.\n");try{

Thread.sleep((long)Math.random()*1000);}catch(InterruptedExceptione){System.out.println(e);}}

textArea.append(Thread.currentThread().getName()+"hasstopped.\n");}publicstaticvoidmain(String[]args){MyThread1t=newMyThread1();Threadt1=newThread(t,"Thread1");Threadt2=newThread(t,"Thread2");t1.start();t2.start();}}线程的建立举例多线程的控制1.操作线程如果创建线程正常,可在线程的run()方法里控制线程。一旦进入run()方法,便可执行里面的任何程序。run()好象main()一样。一旦run()执行完,这个线程也就结束了。若想推迟一个线程的执行,应使用sleep(delay)休眠方法,delay是休眠的时间(毫秒)。当线程休眠时并不占用系统资源。其他线程可继续工作。2.暂停一个线程经常需要挂起一个线程而不指定多少时间。例如,若创建了一个含有动画线程的小程序。也许让用户暂停动画直到他们想恢复为止。若不想将动画线程扔掉,但想让它停止,象这种类似的线程可用suspend()方法来挂起。用suspend()方法挂起线程并不永久地停止线程,这可用resume()方法重新激活线程。3.停止一个线程线程的最后一个控制是停止方法stop()。用它可以停止线程的执行。多线程的(同步)互斥程序中的多个线程一般是独立运行的,各个线程有自己的数据和方法。但有时需要在多个线程之间共享一些资源对象,这些资源对象的操作在某些时候必须要在线程间很好地协调,以保证它们的正确使用。不考虑协调性,就可能产生错误。

在Java语言中,为保证线程对共享资源操作的完整性,用关键字synchronized为共享资源加锁来解决这个问题。从而达到对共享数据的互斥访问。如果一个线程获得了锁,所有其他希望获得该锁从而对共享数据进行访问的线程将被暂停,进入等待状态,直到前一个线程完成了对共享数据的访问,释放了该锁为止,通常称这个锁为互斥锁。synchronized可修饰一个代码块或一个方法,使修饰对象在任一时刻只能有一个线程访问。从而提供了程序的异步执行功能。使用synchronized的形式为:

synchronized(this){......}//修饰一个代码块

synchronizedmethodName(parameters){//修饰一个方法

......}多线程的交互有时候,多个线程需要相互协作来共同完成一个任务,这需要在多个线程之间存在着一种交互机制。实现交互需要在这些线程之间相互通讯。Java提供了方法wait()和notify()等来使线程之间相互交谈。一个线程可以进入某一个对象的synchronized方法进入等待状态,直到其他线程显式地将它唤醒。可以有多个线程进入同一个方法并等待同一个唤醒消息。多线程的应用【例】一个Java小程序。在屏幕上显示时间,每隔一秒钟刷新一次。为使小程序不影响其他程序的运行,使用了多线程。importjava.awt.*;importjava.applet.*;importjava.util.Date;publicclassClockextendsAppletimplementsRunnable{ThreadclockThread;Fontfont;

publicvoidinit(){font=newFont("TimesRoman",Font.BOLD,64);}publicvoidstart(){if(clockThread==null){

clockThread=newThread(this,"Showtime");

clockThread.start();}}publicvoidrun(){while(clockThread!=null){repaint();try{clockThread.sleep(1000);}catch(InterruptedExceptione){}

}}publicvoidpaint(Graphicsg){Datenow=newDate();

g.setFont(font);

g.setColor(Color.red);

g.drawString(now.getHours()+":"+

now.getMinutes()+":"

+now.getSeconds(),5,50);}publicvoidstop(){

clockThread.stop();}}程序运行结果如下图所示。补充JDBC数据库编程技术(1学时)知识点:了解常见的关系型数据库熟悉JDBC的工作原理,掌握JDBC操作数据库所用到的类的使用方法掌握JDBC开发数据库的工作步骤本节主要介绍以下5个部分的内容:1.关系数据库简介2.JDBC基础3.主要JDBC类4.JDBC编程工作步骤5.实例一、关系数据库简介

(1)关系数据库的特点有哪些?

一个数据库由一个或多个表组成,每个表由行,列组成,列代表字段(即属性),行代表记录,表中的记录应该是唯一的,主关键字唯一。(2)对关系数据库的操作有哪些?

搜索(查找),连接操作 添加,更新,删除记录

(3)SQL语句(1)SELECT[ALL|DISTINCT|DISTINCTROW|TOP]

{*|talbe.*|[table.]field1[ASalias1][,[table.]field2[ASalias2][,…]]}

FROMtableexpression[,…][INexternaldatabase]

[WHERE…]

(2)更新数据语法:

UPDATE表名

SET新值

WHERE条件

(3)DELETE子句的语法:

DELETE[表名.*]

FROM来源表

WHERE条件(4)INSERT子句的语法:

INSETRINTO目的表或查询(字段1,字段2,…)

values(数值1,数值2,…)二ODBC概述30ODBC(OpenDatabaseConnectivity

)定义:

ODBC是一种用来在相关和不相关的DBMS中存取数据的标准应用程序数据接口。ODBC组成:应用程序接口为数据库应用程序开发者提供了统一的SQL编程接口数据库驱动器实现ODBCAPI(ODBC)的函数调用,ODBCAPI是数据库厂商为程序设计者提供的一组直接访问数据库的函数驱动程序管理器用于为应用程序装载数据库驱动器,为应用程序与数据库之间的操作选择相互匹配的ODBCAPI函数数据源数据源是数据库位置、数据库类型以及ODBC驱动程序等信息的集成三、JDBC基础

JDBC是为Java提供的一个平台无关的数据库标准API,它提供了一个通用的SQL数据库存取机制,该机制为多数关系型DBMS提供统一接口。

JDBC分为JDBCAPI与JDBC驱动程序。前者即一组JDBC类库,使用这个类库可以以一种标准的方法、方便地访问数据库资源(在java.sql类包中)。

JDBC为访问不同的数据库提供了一种统一的途径,象ODBC一样,JDBC对开发者屏蔽了一些细节问题。二、JDBC基础

JDBC包含一系列丰富的类,在java.sql包中(JDK.1.1以上).JDBC提供了一种API实现对数据库透明存取的方法,这种存取依据驱动程序来实现,不同的数据库制造尚提供它们不同的驱动程序.JDBC的目标是使应用程序开发人员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。与ODBC相类似,JDBC接口(API)也包括两个层次:

面向应用的API:JavaAPI,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。

面向数据库的API:JavaDriverAPI,供开发商开发数据库驱动程序用。JDBC直接在应用程序中加载驱动程序并连接特定的数据库。二、JDBC基础三、主要JDBC类(1)Driver类:用来与数据库通信的软件.(2)DriverManager类:是JDBC基础,用来管理和卸载JDBC驱动程序.该类有一个getConnection()方法,用于验证JDBC数据源,并返回Connection对象.(3)Connection类:该类的CreateStatement()方法连接JDBC数据源,返回Statement对象.(4)Statement类:将SQL行为封装起来交给数据库引擎,调用该类的execute(),executeQuery(),executeUpdate()等方法,执行SQL语句,返回resultSet对象.(5)ResultSet类:封装了一个由SQL查询返回的结果.该类的getString(),getInt()等方法获得一栏数据的存取,next()方法到下一行.四、JDBC编程工作步骤任何一个JDBC应用程序,都需要以下四个步骤:加载JDBC驱动程序建立与数据库的连接进行数据库操作数据集结果分析关闭相关连接1、加载JDBC驱动程序在应用程序中,有三种方法可以加载驱动程序:利用System类的静态方法setProperty()System.setProperty(“jdbc.drivers”,“sun.jdbc.odbc.JdbcOdbcDriver”);

利用Class类的静态方法forName()Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);Class.forName(“oracle.jdbc.driver.OracleDriver”);

直接创建一个驱动程序对象new

sun.jdbc.odbc.JdbcOdbcDriver();2、通过JDBC访问数据库37JDBC驱动程序分类JDBC-ODBC和ODBCDriver相关数据库提供的JDBC驱动程序2、通过JDBC访问数据库38通过JDBC-ODBC来连接数据库设置ODBC数据源2、通过JDBC访问数据库39通过JDBC-ODBC来连接数据库加载驱动JDBC-ODBC驱动器try{

Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

}catch(ClassNotFoundExceptione){}

解释:“sun.jdbc.odbc.JdbcOdbcDriver”是驱动器类的名字以完整的Java类名为参数,装载此类,并返回一个Class对象同时,自动创建一个驱动器类的实例并自动调用驱动器管理器DriverManager类中的RegisterDriver方法来注册它2、通过JDBC访问数据库40通过JDBC-ODBC来连接数据库建立与数据库的连接Connectioncon=DriverManager.getConnection("jdbc:odbc:PIMS","test","1234");解释:将返回与指定数据库建立的连接该方法有三个字符串参数第一个是JDBCURL,格式为jdbc:子协议:子名称jdbc表示协议,JDBCURL中的协议总是jdbc;子协议是驱动器名称;子名称是数据库的名称,如果是位于远程服务器上的数据库,则还应该包括网络地址,//主机名:端口/数据库名第二个是访问数据库所需的用户名第三个是用户密码Connection是一个接口,表示与指定数据库的连接通过JDBC访问数据库41通过JDBC-ODBC来连接数据库对数据库进行操作使用Connection对象创建Statement对象使用Statement对象执行SQL命令从上一步骤返回的ResultSet对象中提取执行结果通过JDBC访问数据库42Connection接口有3个方法可用来创建向数据库发送SQL语句的对象createStatement创建向数据库发送SQL语句的Statement对象,用于简单的SQL语句

Statementstmt=con.createStatement();prepareStatement创建向数据库发送SQL语句的PreparedStatement对象,用于带有一个或多个参数的SQL语句。在SQL语句执行前,这些参数将被赋值prepareCall创建向数据库发送SQL语句的CallableStatement对象,用于调用数据库中的存储过程通过JDBC访问数据库43Statement接口提供了三种执行SQL语句的方法,使用哪一个方法由SQL语句所产生的内容决定executeQuery用于产生单个结果集的语句,例如SELECT语句

ResultSet

rs=stmt.executeQuery("Select*FromPerson");executeUpdate用于执行INSERT、UPDATE或DELETE语句,以及CREATETABLE

stmt.executeUpdate("DELETEFROMPersonWHEREName='李四'");返回值是一个整数,表示受影响的行数(即更新计数Execute用于执

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论