Java编程 第七章.ppt_第1页
Java编程 第七章.ppt_第2页
Java编程 第七章.ppt_第3页
Java编程 第七章.ppt_第4页
Java编程 第七章.ppt_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

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

文档简介

1、线 程,程序是由若干条语句组成的语句序列,是一段静态代码。 进程是程序的一次动态执行过程。 一个线程是一个程序内部的顺序执行控制流。,程序、进程、线程和多线程,main(String args). aa();. aa()bb(); bb(). ,单线程,Public void run();.,一个线程(或执行上下文)由三个主要部分组成 l 一个虚拟CPU l CPU执行的代码 l 代码操作的数据,多线程:在同一应用程序中,有多个顺序流同时执行。,线程和进程 多进程:在操作系统中,能同时运行多个程序 (任务)。 多线程:在同一应用程序中,有多个顺序流同时执行。 每个进程都有独立的代码和数据空间(

2、进程上下文),进程切换的开销大。 线程:轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。,线程的概念模型,虚拟的CPU,封装在java.lang.Thread类中。 CPU所执行的代码,传递给Thread类。 CPU所处理的数据,传递给Thread类。,线程体,Java的线程是通过java.lang.Thread类来实现的。 每个线程都是通过某个特定Thread对象的方法run( )来完成其操作的,方法run( )称为线程体。,线程的状态(四态),创建状态(new Thread) Thread myThread = new MyThrea

3、dClass( ); 可运行状态( Runnable ) Thread myThread = new MyThreadClass( ); myThread.start( );,不可运行状态(Not Runnable) 调用了sleep()方法; 调用了suspend()方法; 为等候一个条件变量,线程调用wait()方法; 输入输出流中发生线程阻塞; 死亡状态(Dead) 线程的终止一般可通过两种方法实现:自然撤消(线程执行完)或是被停止(调用stop()方法)。,线程体的构造,public Thread( ThreadGroup group, Runnable target, String

4、name ); 任何实现接口Runnable的对象都可以作为一个线程的目标对象;,构造线程体的2种方法 定义一个线程类,它继承类Thread并重写其中的方法run( ); 创建一个实现Runnable接口的类作为线程的目标对象,在初始化一个Thread类或者Thread子类的线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体run( )。public Thread(Runnabletarget),通过继承类Thread构造线程体,class SimpleThread extends Thread public SimpleThread(String str) super(str)

5、; public void run() for (int i = 0; i 10; i+) System.out.println(i + + getName(); try sleep(int)(Math.random() * 1000); catch (InterruptedException e) ,System.out.println(DONE! + getName(); public class TwoThreadsTest public static void main (String args) new SimpleThread(First).start(); new SimpleT

6、hread(Second).start(); ,0 First 0 Second 1 Second 1 First 2 First 2 Second 3 Second 3 First 4 First 4 Second 5 First 5 Second 6 Second,6 First 7 First 7 Second 8 Second 9 Second 8 First DONE! Second 9 First DONE! First,通过接口构造线程体,public class Clock extends java.applet.Applet implements Runnable Threa

7、d clockThread; public void start() if (clockThread = null) clockThread = new Thread(this, Clock); clockThread.start(); ,public void run() while (clockThread != null) repaint(); try clockThread.sleep(1000); catch (InterruptedException e) ,public void paint(Graphics g) Date now = new Date(); g.drawStr

8、ing(now.getHours() + : + now.getMinutes() + :+now.getSeconds(), 5, 10); public void stop() clockThread.stop(); clockThread = null; ,两种方法的比较,使用Runnable接口 可以将CPU,代码和数据分开,形成清晰的模型; 还可以从其他类继承; 保持程序风格的一致性。 直接继承Thread类 不能再从其他类继承; 编写简单,可以直接操纵线程,无需使用Thread.currentThread()。,线程的调度,Java提供一个线程调度器来监控程序中启动后进入就绪状态的

9、所有线程。线程调度器按照线程的优先级决定应调度哪些线程来执行。 线程的调度是抢先式的。 时间片方式 非时间片方式,下面几种情况下,当前线程会放弃CPU: 线程调用了yield()或sleep()方法主动放弃; 由于当前线程进行I/O访问,外存读写,等待用户输入等操作,导致线程阻塞; 为等候一个条件变量,线程调用wait()方法; 抢先式系统下,由高优先级的线程参与调度;时间片方式下,当前时间片用完,由同优先级的线程参与调度。,线程的优先级,线程的优先级用数字来表示,范围从1到10,即Thread.MIN_PRIORITY到Thread.MAX_PRIORITY。一个线程的缺省优先级是5,即Th

10、read.NORM_PRIORITY。 int getPriority(); void setPriority(int newPriority);,class ThreadTest public static void main( String args ) Thread t1 = new MyThread(T1); t1.setPriority( Thread.MIN_PRIORITY ); t1.start( ); Thread t2 = new MyThread(T2); t2.setPriority( Thread.MAX_PRIORITY ); t2.start( ); Thread

11、 t3 = new MyThread(T3); t3.setPriority( Thread.MAX_PRIORITY ); t3.start( ); ,class MyThread extends Thread String message; MyThread ( String message ) this.message = message; public void run() for ( int i=0; i3; i+ ) System.out.println( message+ +getPriority() ); ,运行结果: T2 10 T2 10 T2 10 T3 10 T3 10

12、 T3 10 T1 1 T1 1 T1 1,注意:并不是在所有系统中运行Java程序时都采用时间片策略调度线程,所以一个线程在空闲时应该主动放弃CPU,以使其他同优先级和低优先级的线程得到执行。,基本的线程控制,终止线程 线程执行完其run()方法后,会自然终止。 通过调用线程的实例方法stop()来终止线程。 测试线程状态 可以通过Thread中的isAlive()方法来获取线程是否处于活动状态; 线程由start()方法启动后,直到其被终止之间的任何时刻,都处于 Alive状态。,线程的暂停和恢复 sleep()方法 join() 当前线程等待调用该方法的线程结束后,再恢复执行. Time

13、rThread tt=new TimerThread(100); tt.start(); public void timeout() tt.join();/等待线程tt执行完后再继续往下执行 ,多线程的互斥与同步,临界资源问题 class stack int idx=0; char data = new char6; public void push(char c) dataidx = c; idx+; ,public char pop() idx-; return dataidx; 两个线程A和B在同时使用Stack的同一个实例对象,A正在往堆栈里push一个数据,B则要从堆栈中pop一个数

14、据。 1) 操作之前 data = | p | q | | | | | idx=2 2) A执行push中的第一个语句,将r推入堆栈; data = | p | q | r | | | | idx=2,3)A还未执行idx+语句,A的执行被B中断,B执行pop方法,返回q: data = | p | q | r | | | | idx=1 4A继续执行push的第二个语句: data = | p | q | r | | , | | idx=2 最后的结果相当于r没有入栈。 产生这种问题的原因在于对共享数据访问的操作的不完整性。,在Java 语言中,引入了对象互斥锁的概念,来保证共享数据操作的完

15、整性。 每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。 关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。,public void push(char c) synchronized(this) dataidx=c; idx+; public char pop() synchronized(this) idx-; return dataidx; ,synchronized 除了象上面讲的放在对象前面限制一段代码的执行外,还可以放在方法声明中,表示整个方法为

16、同步方法。 public synchronized void push(char c) 如果synchronized用在类声明中,则表明该类中的所有方法都是synchronized的。,多线程的同步,class SyncStack private int index = 0; private char buffer = new char6; public synchronized void push(char c) while(index = buffer.length) try this.wait(); catch(InterruptedException e) ,this.notify()

17、; bufferindex = c; index+; public synchronized char pop() while(index =0) try this.wait(); catch(InterruptedException e) ,this.notify(); index- -; return bufferindex; ,生产者-消费者问题,class Producer implements Runnable SyncStack theStack; public Producer(SyncStack s) theStack = s; ,public void run() char

18、c; for(int i=0; i20; i+) c =(char)(Math.random()*26+A); theStack.push(c); System.out.println(Produced: +c); tryThread.sleep(int)(Math.random()*100); catch(InterruptedException e) ,class Consumer implements Runnable SyncStack theStack; public Consumer(SyncStack s) theStack = s; ,public void run() cha

19、r c; for(int i=0;i20;i+) c = theStack.pop(); System.out.println(Consumed: +c); tryThread.sleep(int)(Math.random()*1000); catch(InterruptedException e) ,public class SyncTest public static void main(String args) SyncStack stack = new SyncStack(); Runnable source=new Producer(stack); Runnable sink = n

20、ew Consumer(stack); Thread t1 = new Thread(source); Thread t2 = new Thread(sink); t1.start(); t2.start(); ,程序执行结果,Produced:V Consumed:V Produced:E Consumed:E Produced:P Produced:L . Consumed:L Consumed:P,wait(),notify(),notifyAll(),(1) wait,nofity,notifyAll必须在已经持有锁的情况下执行,所以它们只能出现在synchronized作用的范围内.

21、 (2) wati的作用:释放已持有的锁,进入wait队列. (3) notify的作用:唤醒wait队列中的一个线程并把它移入锁申请队列. (4) notifyAll的作用:唤醒wait队列中的所有的线程并把它们移入锁申请队列.,模拟考题,Question 9) Which of the following are methods of the Runnable interface 1) run 2) start 3) yield 4) stop,模拟考题,Answer to Question 9) 1) The Runnable interface has only one method

22、run that needs to be created in any class that implements it. The start method is used to actually call and start the run method executing.,模拟考题,Question 35) What will happen when you attempt to compile and run the following code public class Borley extends Thread public static void main(String argv

23、) Borley b = new Borley(); b.start(); public void run() System.out.println(Running); ,模拟考题,1) Compilation and run but no output 2) Compilation and run with the output Running 3) Compile time error with complaint of no Thread target 4) Compile time error with complaint of no access to Thread package,

24、模拟考题,Answer to Question 35) 2) Compilation and run with the output Running,模拟考题,Question 44) Given a reference called t to a class which extends Thread, which of the following will cause it to give up cycles to allow another thread to execute. 1) t.yield(); 2) yield(); 3) yield(100); /Or some other

25、suitable amount in milliseconds 4) yield(t);,模拟考题,Answer to Question 44) 1) t.yield(); 2) yield(),Java Applet 介绍,什么是Applet?,Applet就是使用Java语言编写的一段代码,它可以在浏览器环境中运行。它与Application的区别主要在于其执行方式的不同。 application是从其中的main()方法开始运行的 Applet是在浏览器中运行的,必须创建一个HTML文件,通过编写HTML语言代码告诉浏览器载入何种Applet以及如何运行。,Applet 举例,Hello

26、World.java 源程序: import java.awt.Graphics; import java.applet.Applet; public class HelloWorld extends Applet String hw_text ; public void init () hw_text = Hello World; ,public void paint(Graphics g) g.drawString (hw_text , 25, 25) ; ,Applet的 运行,为运行Applet需要编写相应的HTML文件: ,Applet的 安全性,“沙箱”机制 浏览器禁止Applet

27、执行下列操作: (1)在运行时调用其它程序 (2)文件读写操作 (3)装载动态连接库和调用任何本地方法 (4)试图打开一个socket进行网络通信,但是所连接的主机并不是提供Applet的主机,Applet的类层次,java.lang.Object | +.java.awt.Componet | +.java.Container | +.java.awt.Panel | +.java.applet.Applet,Applet的主要方法,init( ) 创建Applet时执行,只执行一次 start( ) 多次执行,当浏览器从图标恢复成窗口,或者是返回该主页时执行 stop( ) 多次执行,停止

28、一些耗用系统资源的工作, 浏览器变成图标时,或者是离开主页时执行 destroy( ) 用来释放资源,在stop( )之后执行,Applet的生命周期,destroy,第一次装入,构造、init,例13.2 import java.awt.Graphics; import java.applet.Applet; public class HWloop extends Applet AudioClip sound; public void init( ) sound=getAudioClip(“audio/hello.au”); public void paint(Graphics g) g.d

29、rawString(“hello Audio”,25,25); ,public void start( ) sound.loop( ); public void stop( ) sound.stop( ); ,Applet标记,applet archive=archiveList /*同一个codebase中需先下载的文件 */ code=appletFile.class /applet的名称 width=pixels height=pixels /applet的初始显示空间 codebase=codebaseURL /代码的地址 alt=alternateText /不支持applet时,显

30、示的替代文本 name=appletInstanceName /*给该applet取名,用于同页面applet之间的通信 */ align=alignment /对齐,如left,right,top,baseline.,Applet标记,vspace=pixels hspace=pixels /预留的空白 /参数名称及其值 alternateHTML ,Applet标记,不支持Java的浏览器会把之间的普通HTML文档显示出来;支持Java的浏览器,则把其中的普通HTML文档忽略 AppletViewer仅支持 标记,其它标记不会被显示出来。,同时是Applet与Application,例13

31、.3 import java.awt.*; import java.awt.event.*; public class AppletApp extends Applet public void main(String args) Frame frame=new Frame(“Application”); AppletApp app=new AppletApp(); frame.add(“Center”,app); frame.setSize(200,200);,frame.validate(); frame.setVisible(true); frame.addWindwoListener(n

32、ew WindowControl(app); app.init(); app.start(); public void paint(Graphics g) g.drawString(“hello world”,25,25); public void destroy() System.exit(0); ,class WindowControl extends WindowAdapter Applet c; public WindowControl(Applet c) this.c=c; public void windowClosing(WindowEvent e) c.destroy( );

33、,Applet的AWT绘制,paint( ) 进行绘图的具体操作,必须重写 update( ) 用于更新图形,先清除背景、前景,再调用paint() repaint( ) 用于重绘图形,在组件外形发生变化,即大小改变或位置移动时,repaint( )方法立即被系统自动调用,Applet的AWT绘制,update( ) clear area call paint( ),paint( ),AWT Thread(Waiting),遮盖、调整大小、 最大最小化等等,程序调用 repaint( ),java.awt.Graphics类,update( )和paint( )的参数 支持基本的绘图和画图像

34、void drawLine( ) void drawArc( ) void drawPolygon( ) void drawRect( ) void drawRoundRect( ) void fill3DRect( ) void fillOval( ),java.awt.Graphics类,输出文字 void drawBytes( ) void drawChars( ) void drawString( ),Applet 的AWT绘制举例,import java.awt.*; import java.awt.event.*; import java.applet.*; public clas

35、s ArcTest extends Applet implements WindowListener ArcControls controls; pulic void init() setLayout(new BorderLayout(); ArcCanvas c=new ArcCanvas();,Add(“Center”,c); add(“South”,controls=new ArcControls(C); public void start() controls.setEnabled(true); public void stop() controls.setEnabled(false)

36、; public void windowActivated(WindowEvent e) public void windowClosed(WindowEvent e) public void windowClosing(WindowEvent e) System.exit(0); ,public void windowDeactivated(WindowEvent e) public void windowDeiconified(WindowEvent e) public void windowIconified(WindowEvent e) public void windowOpend(

37、WindowEvent e) public static void main(String args) Frame f=new Frame(“ArcTest”); ArcTest arcTest=new ArcTest(); atcTest.init(); arcTest.start(); f.add(“Center”,arcTest); f.setSize(300,300); f.show();,f.addWindowListener(arcTest); class ArcCanvas extends Canvas int startAngle=0; int endAngle=45; boo

38、lean filled=false; Font font; public void paint(Graphics g) Rectangle r=getBounds(); int hlines=r.height/10; int vlines=r.width/10; g.setColor(Color.pink);,for(int i=1;i=hlines;i+) g.drawLine(0,i*10,r.width,i*10); for(int i=1;i=vlines;i+) g.drawLine(i*10,0,i*10,r.height); g.setColor(Color.red); if(f

39、illed) g.fillArc(0,0,r.width-1,r.height-1,startAngle,endAngle); else g.drawArc(0,0,r.width-1,r.height-1,startAngle, endAngle); ,g.setColor(Color.black); g.setFont(font); g.drawLine(0,r.height/2,r.width,r.height/2); g.drawLine(r.width/2,0,r.width/2,r.height); g.drawLine(0,0,r.width,r.height); g.drawL

40、ine(r.width,0,0,r.height); int sx=10; int sy=r.height-28; g.drawString(“S=“+startAngle,sx,sy); g.drawString(“E=“+ednAngle,sx,sy+14); ,public void redraw(boolean filled,int start,int end) this.filled=filled; this.startAngle=start; this.endAngle=end; repaint(); class ArcControls extends Panel implemen

41、ts ActionListener TextFiled s; TextFiled e; ArcCanvas canvas;,public ArcControls(ArcCanvas canvas) Button b=null; this.canvas=canvas; add(s=new TextField(“0”,4); add(e=new TextField(“45”,4); b=new Button(“Fill”); b.addActionListener(this); add(b); b=new Button(“Draw”); b.addActionListener(this); add(b); ,public void actionPerformed(ActionEvent ev) String label=ev.getActionCommand(); canvas.redraw(label.equals(“Fill”), Integer.parseInt(s.getText(),trim(), Integer.parserInt(e.getText().trim(); ,Applet和浏览器间的通信,getDocumentBase( ) 返回当前网页所在的URL getCodeBase(

温馨提示

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

最新文档

评论

0/150

提交评论