- 浏览: 87363 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (148)
- 全文检索 (1)
- java (29)
- xml (2)
- json (2)
- redis springmvc (1)
- Redis (5)
- 开发常识 (1)
- tomcat (2)
- 单元测试Junit (2)
- 设计模式 (2)
- spring (10)
- jvm (2)
- eclipse (4)
- echart (1)
- mybatis (1)
- mysql (3)
- web (1)
- js (2)
- PL/SQL (2)
- 其他 (1)
- 人生 (1)
- 安全 (2)
- jsp (2)
- 硬件电脑 (1)
- linux (3)
- git (10)
- oracle (8)
- ant (1)
- maven (2)
- 正则表达式 (2)
- chrome (1)
- 面试 (6)
- 多线程 (19)
- bug (11)
- java工具类 (3)
- 算法 (1)
- bug,git (1)
- shell (2)
- springmvc (2)
- Java8 (1)
- 消息队列-rocketmq (1)
- es (1)
- dubbo (0)
- spring cloud (0)
- hashmap (0)
- springboot (1)
- velocity (0)
本例演示线程对象的生命周期从创建到终止的过程,使用new、start()、sleep()、interrupt()等方法改变线程的状态。 本例综合运用内部类、图形化用户界面、线程等多方面技术实现设计。
运行效果图:
框架窗口由多个面板组成,每个面板布局相同,上部文本行中的字符串向左移动,下部有多个组件,用于设置字符串移动速度、控制字符串是否移动和显示线程状态。
sleep右边的文本行,用于改变线程睡眠时间,以控制字符串的移动速度;
单击“启动”按钮,则启动线程,使字符串移动;
单击“中断”按钮,则中断线程运行。
jvisualVM命令监控线程状态图
程序说明:
(1)声明自定义面板类为私有内部类并实现多个接口
本例需要在一个窗口中添加若干同样风格的面板,添加的面板数不确定,且每个面板组成较复杂,因此将自定义的面板设计成内部类。根据外部类构造方法的texts数组长度,将若干个面板添加到是外部类的框架窗口中。
由于面板内部类RollbyJPanel 只有其外部类使用,所以RollbyJPanel类声明为私有成员;由于面板中的按钮和文本行组件需要响应单击事件,所以RollbyJPanel类声明实现ActionListener接口;由于每个面板都对应着一个线程对象,而RollbyJPanel类已继承JPanel类,无法再继承Thread类,所以RollbyJPanel类声明实现Runnable接口,其中声明一个线程对象作为成员变量,Runnable类对象是其线程成员变量的目标对象。
虽然RollbyJPanel类是私有的,但其中的run()和actionPerformed()方法必须是公有的,因为这两个方法在接口中声明公有。
(2)线程状态变化
面板内部类RollbyJPanel 中声明一个线程对象thread_rollby,通过该线程对象控制字符串是否移动以及移动速度。线程启动后执行线程run()方法,将字符串首字符连接到字符串最后,通过线程睡眠控制字符串显示一段时间,再次重新循环移位字符串,达到看起来像是字符串在移动的效果。
线程运行中,单击“中断”按钮,调用interrupt()方法为当前线程对象设置中断标记,该中断标记由sleep()方法获知并抛出InterruptedException异常。在异常处理语句中,使用break语句退出循环,使run()方法结束,则线程对象终止。再次单击“启动”按钮,则重新创建一个线程对象并启动。各面板的线程状态变化与其他面板的线程状态无关。
package com.jbx.thread; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Arrays; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; public class WelcomeJFrame extends JFrame { public WelcomeJFrame(String[] texts) //texts指定移动字符串,数组长度决定窗口中的面板数 { super("滚动字"); this.setBounds(300, 240, 400, 300); this.setDefaultCloseOperation(EXIT_ON_CLOSE); if(texts==null || texts.length==0) this.getContentPane().add(new RollbyJPanel("Welcome!"));//至少有一行字符串 else{ this.getContentPane().setLayout(new GridLayout(texts.length,1)); //网格布局,1行若干列 for(int i=0;i<texts.length;i++){ this.getContentPane().add(new RollbyJPanel(texts[i])); } } this.setVisible(true); } public WelcomeJFrame() { this(null); } private class RollbyJPanel extends JPanel implements ActionListener,Runnable { JTextField text_word,text_sleep; //滚动字文本行,线程睡眠时间文本行 JButton button_start,button_interrupt; //启动按钮,中断按钮 JTextField text_state; //线程状态文本行 Thread thread_rollby; //线程对象 int sleeptime; //线程睡眠时间 RollbyJPanel(String text) //内部面板类构造方法 { this.setLayout(new GridLayout(2,1)); char space[] = new char[100]; Arrays.fill(space, ' '); //将字符数组space填充满空格 text_word = new JTextField(text+new String(space)); //text后加空格字符串 this.add(text_word); JPanel panel_sub = new JPanel(new FlowLayout(FlowLayout.LEFT)); this.add(panel_sub); panel_sub.add(new JLabel("sleep")); this.sleeptime=(int)(Math.random()*100);//产生随机数作为间隔时间 text_sleep = new JTextField(""+sleeptime,5); panel_sub.add(text_sleep); text_sleep.addActionListener(this); button_start = new JButton("启动"); panel_sub.add(button_start); button_start.addActionListener(this); button_interrupt = new JButton("中断"); panel_sub.add(button_interrupt); button_interrupt.addActionListener(this); thread_rollby = new Thread(this); //创建线程对象,目标对象是当前对象 button_interrupt.setEnabled(false); //设置中断按钮为无效状态 panel_sub.add(new JLabel("state")); text_state = new JTextField(""+thread_rollby.getState(),10); text_state.setEditable(false); panel_sub.add(text_state); } @Override public void run() { //线程体,必须是公有方法 while(true) try{ String str = text_word.getText(); str = str.substring(1) + str.substring(0,1); text_word.setText(str); thread_rollby.sleep(sleeptime); //线程睡眠,抛出中断异常 }catch(InterruptedException e){ break; //退出循环 } } //run()方法结束,线程对象终止 @Override public void actionPerformed(ActionEvent e) { //单击事件处理,必须是公有方法 if(e.getSource() == button_start){ //单击启动按钮时 thread_rollby = new Thread(this); //重新创建一个线程对象 thread_rollby.start(); text_state.setText(""+thread_rollby.getState()); //显示线程状态 button_start.setEnabled(false); button_interrupt.setEnabled(true); } if(e.getSource() == button_interrupt){ //单击中断按钮时 thread_rollby.interrupt(); //设置当前线程对象中断标记 text_state.setText(""+thread_rollby.getState()); //显示线程状态 button_start.setEnabled(true); button_interrupt.setEnabled(false); } if(e.getSource() == text_sleep){ //单击线程睡眠时间文本行时 try{ sleeptime = Integer.parseInt(text_sleep.getText()); }catch(NumberFormatException nfe){ JOptionPane.showMessageDialog(this, "\""+text_sleep.getText()+"\" 不能转换成整数,请重新输入!"); } } } } public static void main(String[] args) { String[] texts ={"Welcome","Hello","Rollby","girl"}; new WelcomeJFrame(texts); } }
运行效果图:
框架窗口由多个面板组成,每个面板布局相同,上部文本行中的字符串向左移动,下部有多个组件,用于设置字符串移动速度、控制字符串是否移动和显示线程状态。
sleep右边的文本行,用于改变线程睡眠时间,以控制字符串的移动速度;
单击“启动”按钮,则启动线程,使字符串移动;
单击“中断”按钮,则中断线程运行。
jvisualVM命令监控线程状态图
程序说明:
(1)声明自定义面板类为私有内部类并实现多个接口
本例需要在一个窗口中添加若干同样风格的面板,添加的面板数不确定,且每个面板组成较复杂,因此将自定义的面板设计成内部类。根据外部类构造方法的texts数组长度,将若干个面板添加到是外部类的框架窗口中。
由于面板内部类RollbyJPanel 只有其外部类使用,所以RollbyJPanel类声明为私有成员;由于面板中的按钮和文本行组件需要响应单击事件,所以RollbyJPanel类声明实现ActionListener接口;由于每个面板都对应着一个线程对象,而RollbyJPanel类已继承JPanel类,无法再继承Thread类,所以RollbyJPanel类声明实现Runnable接口,其中声明一个线程对象作为成员变量,Runnable类对象是其线程成员变量的目标对象。
虽然RollbyJPanel类是私有的,但其中的run()和actionPerformed()方法必须是公有的,因为这两个方法在接口中声明公有。
(2)线程状态变化
面板内部类RollbyJPanel 中声明一个线程对象thread_rollby,通过该线程对象控制字符串是否移动以及移动速度。线程启动后执行线程run()方法,将字符串首字符连接到字符串最后,通过线程睡眠控制字符串显示一段时间,再次重新循环移位字符串,达到看起来像是字符串在移动的效果。
线程运行中,单击“中断”按钮,调用interrupt()方法为当前线程对象设置中断标记,该中断标记由sleep()方法获知并抛出InterruptedException异常。在异常处理语句中,使用break语句退出循环,使run()方法结束,则线程对象终止。再次单击“启动”按钮,则重新创建一个线程对象并启动。各面板的线程状态变化与其他面板的线程状态无关。
发表评论
-
ThreadPoolExecutor线程池参数详解
2019-01-09 00:06 458参考:https://www.cnblogs.com/wayt ... -
解决线程同步问题的思路
2018-07-31 16:35 402线程同步机制 操作系统中实现线程同步有一种工 ... -
发送线程与接收线程 速率一致
2018-08-07 09:17 373package com.jbx.xiezuo; /* ... -
线程间的协作关系与线程同步
2018-07-30 16:21 5101.线程间的协作关系 当一个进程中的多个线程为完成同 ... -
带互斥锁的并发线程执行流程
2018-07-30 12:38 426... -
线程间的竞争关系与线程互斥
2018-07-30 11:19 648线程间的竞争关系与线 ... -
线程的同步机制
2018-07-17 11:31 351线程的同步机制 (一) ... -
3个线程,A,B,C,这三个线程分别只能打印 “a”,“b”,“c”,怎么让这三个线程依次打印“abc"
2018-07-17 11:19 337package com.jbx.thread; /* ... -
定时器与图形动画设计
2018-07-17 11:15 0动画(animation) 都是利用人眼的视 ... -
线程分类
2018-07-17 09:10 296线程分类: 线程可分为用户线程(user thread) ... -
线程优先级
2018-07-17 09:08 333Java提供10个等级的线程优先级,分别用1~10表示,优先级 ... -
线程对象的生命周期
2018-07-16 11:28 337线程对象的生命周期 1.Thread.State类声明的线程状 ... -
声明实现Runnable接口的奇数/偶数序列线程
2018-07-11 14:02 404package com.jbx.thread; ... -
声明继承Thread类的奇数/偶数序列线程
2018-07-10 23:58 396package com.jbx.com; /** ... -
Java的线程对象Runnable接口和Thread类
2018-07-10 21:42 368Java支持内置的多线程机制。 Java语言包中的Runnab ... -
并发程序设计
2018-07-09 17:22 252并发程序设计 1.顺序程 ... -
线程介绍
2018-07-09 16:55 276线程 1.引入线程机制的 ... -
进程介绍
2018-07-09 15:38 350进程 进程的定义和属性 进程是一个可并发执行的 ... -
多线程
2018-07-09 14:31 292...
相关推荐
04_ScrollBarDemo 演示滚动条控件的使用方法。 05_SpinDemo 演示数值调节按钮的使用方法。 06_ProgressDemo 演示进度条控件的使用方法。 07_SliderDemo 演示滑块控件的使用方法。 08_HotkeyDemo 演示...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
如何让对话框上的文本框在程序启动后立即获得焦点,如何利用SetWindowLong改变窗口的回调函数,通过改变文本框的默认回车处理方式进行演示。实现多个输入文本框间通过回车逐一向下传递焦点的另一种巧妙方法(用缺省...
kenjLV1.zip ListView的API效果演示(10KB) 32,txtsrch.zip 在Text中实现快速增量查询(4KB) 33,TracBar.zip 滚动条模块,与 VB 的滚动条比较,该模块支持动态生成, 支持触发消息(7KB) 34,...
使用.ashx文件处理IHttpHandler实现发送文本及二进制数据的方法 制作一个简单的多页Tab功能 一完美的关于请求的目录不存在而需要url重写的解决方案! 在C#中实现MSN消息框的功能 XmlHttp实现无刷新三联动ListBox 鼠标...
splash.zip 通过自己的线程在Splash对话框中显示文字(136KB)<END><br>6,res_dlg.zip 大小可调的对话框(21KB)<END><br>7,splitter.zip 可变的分割视图(58KB)<END><br>8,anicon1.zip 在窗口的标题条上显示...
带详细说明及vb例子代码(17KB)<END><br>69,tabstatus.zip 在多文档界面的状态条上放一个TAB控件,可以在状态条上直接激活或最大化各个子窗口。(62KB)<END><br>70,pushpin.zip 这个例子演示图钉按纽的实现(就像...
9.32、扫描WIFI热点演示实例教程 246 9.33、调用GOOGLE搜索 249 9.34、调用浏览器 载入某网址 249 9.35、获取 IP地址 249 9.36、从输入流中获取数据并以字节数组返回 250 9.37、通过ANDROID 客户端上传数据到服务器 ...
9.32、扫描WIFI热点演示实例教程 246 9.33、调用GOOGLE搜索 249 9.34、调用浏览器 载入某网址 249 9.35、获取 IP地址 249 9.36、从输入流中获取数据并以字节数组返回 250 9.37、通过ANDROID 客户端上传数据到服务器 ...
修改扩展界面支持库一,为“超级列表框”增加“检查框状态被改变”事件。 15. 修改扩展界面支持库一,为“树形框”增加“是否已加粗()”方法。 16. 修改扩展界面支持库一,为“树形框”增加多态检查框功能,相应...
编译及运行程序(模拟器下) ................................................................................................................ 7 编译及运行程序(PT80) ......................................