看了Thinking in java上的多线程后颇有感触,著文记之。在这里我假设各位都已经拥有了awt和applet的初级知识。
所谓线程,即计算机进程内部的子执行模块,从具体表现上来说,就是独立分配到一部分系统资源而独立于其他可执行代码执行的可执行代码。在java中,实现了语言上的多线程编程。Thinking in java中举了一系列的几个例子来阐述其较为表层的特点。
对于一个拥有ui的程序来说,控制其ui的代码段一般运行在一个线程中,如果想要时刻刷新ui中某些控件的外观,则最好在另一个线程中进行操作,否则可能导致ui线程的阻塞,从而让用户感觉到应用程序停止了交互(例如点击按钮没有了反应等)。例如下面这个取自Thinking in java的计时器案例:
1 packagecom.william.myclient; 2 3 importjava.awt.*; 4 importjava.awt.event.*; 5 importjava.applet.*; 6 7 publicclassCounter1extendsApplet{ 8 9 privateintcount=0; 10 privateButtononOff=newButton("Toggle"),start=newButton("Start"); 11 privateTextFieldt=newTextField(10); 12 privatebooleanrunFlag=true; 13 14 publicvoidinit(){ 15 add(t); 16 start.addActionListener(newStartL()); 17 add(start); 18 onOff.addActionListener(newOnOffL()); 19 add(onOff); 20 } 21 22 publicvoidgo(){ 23 while(true){ 24 try{ 25 Thread.currentThread().sleep(100); 26 } 27 catch(InterruptedExceptione){ 28 29 } 30 if(runFlag) 31 t.setText(Integer.toString(count++)); 32 } 33 } 34 35 classStartLimplementsActionListener{ 36 publicvoidactionPerformed(ActionEvente){ 37 go(); 38 } 39 } 40 41 classOnOffLimplementsActionListener{ 42 publicvoidactionPerformed(ActionEvente){ 43 runFlag=!runFlag; 44 } 45 } 46 47 publicstaticvoidmain(String[]args){ 48 Counter1applet=newCounter1(); 49 FrameaFrame=newFrame("Counter1"); 50 aFrame.addWindowListener(newWindowAdapter(){ 51 publicvoidwindowClosing(WindowEvente){ 52 System.exit(0); 53 } 54 }); 55 aFrame.add(applet,BorderLayout.CENTER); 56 aFrame.setSize(300,200); 57 applet.init(); 58 applet.start(); 59 aFrame.setVisible(true); 60 } 61 }
紧接下来请看如下代码:
1 packagecom.william.myclient; 2 3 importjava.awt.*; 4 importjava.awt.event.*; 5 importjava.applet.*; 6 7 classSeparateSubTaskextendsThread{ 8 privateintcount=0; 9 privateCounter2c2; 10 privatebooleanrunFlag=true; 11 12 publicSeparateSubTask(Counter2c2){ 13 this.c2=c2; 14 start(); 15 } 16 17 publicvoidinvertFlag(){ 18 runFlag=!runFlag; 19 } 20 21 publicvoidrun(){ 22 while(true){ 23 try{ 24 sleep(100); 25 } 26 catch(InterruptedExceptione){ 27 28 } 29 if(runFlag) 30 c2.t.setText(Integer.toString(count++)); 31 } 32 } 33 } 34 35 publicclassCounter2extendsApplet{ 36 TextFieldt=newTextField(10); 37 privateSeparateSubTasksp=null; 38 privateButtononOff=newButton("Toggle"),start=newButton("Start"); 39 40 publicvoidinit(){ 41 add(t); 42 start.addActionListener(newStartL()); 43 add(start); 44 onOff.addActionListener(newOnOffL()); 45 add(onOff); 46 } 47 48 classStartLimplementsActionListener{ 49 publicvoidactionPerformed(ActionEvente){ 50 if(sp==null) 51 sp=newSeparateSubTask(Counter2.this); 52 } 53 } 54 55 classOnOffLimplementsActionListener{ 56 publicvoidactionPerformed(ActionEvente){ 57 if(sp!=null) 58 sp.invertFlag(); 59 } 60 } 61 62 publicstaticvoidmain(String[]args){ 63 Counter2applet=newCounter2(); 64 FrameaFrame=newFrame("Counter2"); 65 aFrame.addWindowListener(newWindowAdapter(){ 66 publicvoidwindowClosing(WindowEvente){ 67 System.exit(0); 68 } 69 }); 70 aFrame.add(applet,BorderLayout.CENTER); 71 aFrame.setSize(300,200); 72 applet.init(); 73 applet.start(); 74 aFrame.setVisible(true); 75 } 76 }
1 packagecom.william.myclient; 2 3 importjava.awt.*; 4 importjava.awt.event.*; 5 importjava.applet.*; 6 7 publicclassCounter2iextendsApplet{ 8 privateclassSeparateSubTaskextendsThread{ 9 intcount=0; 10 booleanrunFlag=true; 11 12 SeparateSubTask(){ 13 start(); 14 } 15 16 publicvoidrun(){ 17 while(true){ 18 try{ 19 sleep(100); 20 }catch(InterruptedExceptione){ 21 22 } 23 if(runFlag) 24 t.setText(Integer.toString(count++)); 25 } 26 } 27 } 28 29 privateSeparateSubTasksp=null; 30 privateTextFieldt=newTextField(10); 31 privateButtononOff=newButton("Toggle"),start=newButton("Start"); 32 33 publicvoidinit(){ 34 add(t); 35 start.addActionListener(newStartL()); 36 add(start); 37 onOff.addActionListener(newOnOffL()); 38 add(onOff); 39 } 40 41 classStartLimplementsActionListener{ 42 publicvoidactionPerformed(ActionEvente){ 43 if(sp==null) 44 sp=newSeparateSubTask(); 45 } 46 } 47 48 classOnOffLimplementsActionListener{ 49 publicvoidactionPerformed(ActionEvente){ 50 if(sp!=null) 51 sp.runFlag=!sp.runFlag;//invertFlag(); 52 } 53 } 54 55 publicstaticvoidmain(String[]args){ 56 Counter2iapplet=newCounter2i(); 57 FrameaFrame=newFrame("Counter2i"); 58 aFrame.addWindowListener(newWindowAdapter(){ 59 publicvoidwindowClosing(WindowEvente){ 60 System.exit(0); 61 } 62 }); 63 aFrame.add(applet,BorderLayout.CENTER); 64 aFrame.setSize(300,200); 65 applet.init(); 66 applet.start(); 67 aFrame.setVisible(true); 68 } 69 } 70
实现代码如下:
1 packagecom.william.myclient; 2 3 importjava.awt.*; 4 importjava.awt.event.*; 5 importjava.applet.*; 6 7 publicclassCounter3extendsAppletimplementsRunnable{ 8 privateintcount=0; 9 privatebooleanrunFlag=true; 10 privateThreadselfThread=null; 11 privateButtononOff=newButton("Toggle"),start=newButton("Start"); 12 privateTextFieldt=newTextField(10); 13 14 publicvoidinit(){ 15 add(t); 16 start.addActionListener(newStartL()); 17 add(start); 18 onOff.addActionListener(newOnOffL()); 19 add(onOff); 20 } 21 22 publicvoidrun(){ 23 while(true){ 24 try{ 25 selfThread.sleep(100); 26 }catch(InterruptedExceptione){ 27 } 28 if(runFlag) 29 t.setText(Integer.toString(count++)); 30 } 31 } 32 33 classStartLimplementsActionListener{ 34 publicvoidactionPerformed(ActionEvente){ 35 if(selfThread==null){ 36 selfThread=newThread(Counter3.this); 37 selfThread.start(); 38 } 39 } 40 } 41 42 classOnOffLimplementsActionListener{ 43 publicvoidactionPerformed(ActionEvente){ 44 runFlag=!runFlag; 45 } 46 } 47 48 publicstaticvoidmain(String[]args){ 49 Counter3applet=newCounter3(); 50 FrameaFrame=newFrame("Counter3"); 51 aFrame.addWindowListener(newWindowAdapter(){ 52 publicvoidwindowClosing(WindowEvente){ 53 System.exit(0); 54 } 55 }); 56 aFrame.add(applet,BorderLayout.CENTER); 57 aFrame.setSize(300,200); 58 applet.init(); 59 applet.start(); 60 aFrame.setVisible(true); 61 } 62 } 63
1 packagecom.william.myclient; 2 3 importjava.awt.*; 4 importjava.awt.event.*; 5 importjava.applet.*; 6 7 classTickerextendsThread{ 8 privateButtonb=newButton("Toggle"); 9 privateTextFieldt=newTextField(10); 10 privateintcount=0; 11 privatebooleanrunFlag=true; 12 13 publicTicker(Containerc){ 14 b.addActionListener(newToggleL()); 15 Panelp=newPanel(); 16 p.add(t); 17 p.add(b); 18 c.add(p); 19 } 20 21 classToggleLimplementsActionListener{ 22 publicvoidactionPerformed(ActionEvente){ 23 runFlag=!runFlag; 24 } 25 } 26 27 publicvoidrun(){ 28 while(true){ 29 if(runFlag) 30 t.setText(Integer.toString(count++)); 31 try{ 32 sleep(100); 33 }catch(InterruptedExceptione){ 34 } 35 } 36 } 37 } 38 39 publicclassCounter4extendsApplet{ 40 privateButtonstart=newButton("Start"); 41 privatebooleanstarted=false; 42 privateTicker[]s; 43 privatebooleanisApplet=true; 44 privateintsize; 45 46 publicvoidinit(){ 47 //Getparameter"size"fromWebpage: 48 if(isApplet) 49 size=Integer.parseInt(getParameter("size")); 50 s=newTicker[size]; 51 for(inti=0;i<s.length;i++) 52 s[i]=newTicker(this); 53 start.addActionListener(newStartL()); 54 add(start); 55 } 56 57 classStartLimplementsActionListener{ 58 publicvoidactionPerformed(ActionEvente){ 59 if(!started){ 60 started=true; 61 for(inti=0;i<s.length;i++) 62 s[i].start(); 63 } 64 } 65 } 66 67 publicstaticvoidmain(String[]args){ 68 Counter4applet=newCounter4(); 69 //Thisisn'tanapplet,sosettheflagand 70 //producetheparametervaluesfromargs: 71 applet.isApplet=false; 72 applet.size=(args.length==0?5:Integer.parseInt(args[0])); 73 FrameaFrame=newFrame("Counter4"); 74 aFrame.addWindowListener(newWindowAdapter(){ 75 publicvoidwindowClosing(WindowEvente){ 76 System.exit(0); 77 } 78 }); 79 aFrame.add(applet,BorderLayout.CENTER); 80 aFrame.setSize(200,applet.size*50); 81 applet.init(); 82 applet.start(); 83 aFrame.setVisible(true); 84 } 85 } 86
好啦,就到这里吧。过年了,大年初一写了这篇博文。在这里祝大家兔年吉祥咯!