- 浏览: 91508 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (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 478参考:https://www.cnblogs.com/wayt ... -
解决线程同步问题的思路
2018-07-31 16:35 418线程同步机制 操作系统中实现线程同步有一种工 ... -
发送线程与接收线程 速率一致
2018-08-07 09:17 384package com.jbx.xiezuo; /* ... -
线程间的协作关系与线程同步
2018-07-30 16:21 5291.线程间的协作关系 当一个进程中的多个线程为完成同 ... -
带互斥锁的并发线程执行流程
2018-07-30 12:38 449... -
线程间的竞争关系与线程互斥
2018-07-30 11:19 672线程间的竞争关系与线 ... -
线程的同步机制
2018-07-17 11:31 385线程的同步机制 (一) ... -
3个线程,A,B,C,这三个线程分别只能打印 “a”,“b”,“c”,怎么让这三个线程依次打印“abc"
2018-07-17 11:19 351package com.jbx.thread; /* ... -
定时器与图形动画设计
2018-07-17 11:15 0动画(animation) 都是利用人眼的视 ... -
线程分类
2018-07-17 09:10 325线程分类: 线程可分为用户线程(user thread) ... -
线程优先级
2018-07-17 09:08 359Java提供10个等级的线程优先级,分别用1~10表示,优先级 ... -
线程对象的生命周期
2018-07-16 11:28 361线程对象的生命周期 1.Thread.State类声明的线程状 ... -
声明实现Runnable接口的奇数/偶数序列线程
2018-07-11 14:02 428package com.jbx.thread; ... -
声明继承Thread类的奇数/偶数序列线程
2018-07-10 23:58 420package com.jbx.com; /** ... -
Java的线程对象Runnable接口和Thread类
2018-07-10 21:42 400Java支持内置的多线程机制。 Java语言包中的Runnab ... -
并发程序设计
2018-07-09 17:22 276并发程序设计 1.顺序程 ... -
线程介绍
2018-07-09 16:55 298线程 1.引入线程机制的 ... -
进程介绍
2018-07-09 15:38 378进程 进程的定义和属性 进程是一个可并发执行的 ... -
多线程
2018-07-09 14:31 313...
相关推荐
以下是一段简单的示例代码,演示了如何实现滚动效果: ```csharp public partial class MainWindow : Window { private DispatcherTimer timer; private double labelWidth; private double moveDistance; ...
9. **多线程考虑**:在复杂的UI应用中,考虑到性能优化,滚动逻辑可能需要放在单独的线程中执行,以避免阻塞主线程导致UI卡顿。 10. **代码组织**:良好的代码组织和模块化设计能让代码更易于维护和扩展。将滚动...
`onScrollStateChanged()`方法会在滚动状态改变时被调用,我们可以在这个方法中判断当前ListView是否正在滚动。 2. **图片加载库**:常见的图片加载库如Glide、Picasso和Universal Image Loader可以帮助我们更高效...
"20个C#窗体设计实例"是一个集合,它包含了一系列示例,帮助开发者深入理解和掌握C#窗体设计的各种技巧和方法。下面,我们将详细探讨这些知识点。 1. **基本窗体创建**:C#中的`System.Windows.Forms.Form`类是所有...
3. **绘图状态**:根据列表项的状态(选中、焦点、鼠标悬停等),可能需要改变绘制的颜色和样式。 4. **性能优化**:自绘可能导致性能下降,因此合理地缓存绘制结果、避免不必要的重绘是非常重要的。 5. **事件...
04_ScrollBarDemo 演示滚动条控件的使用方法。 05_SpinDemo 演示数值调节按钮的使用方法。 06_ProgressDemo 演示进度条控件的使用方法。 07_SliderDemo 演示滑块控件的使用方法。 08_HotkeyDemo 演示...
此外,为了使进度条更加直观,可以使用Style属性改变其样式,如Marquee风格,它会持续滚动,表示操作正在进行中: ```csharp progressBar1.Style = ProgressBarStyle.Marquee; ``` 最后,进度条的外观可以通过设置其...
通过调用`m_ProgressBar.SendMessage(PBM_SETBARCOLOR, 0, (LPARAM)color)`可以改变进度条的颜色,而`m_ProgressBar.SendMessage(PBM_SETSTATE, state, 0)`可以设置不同状态,如平滑滚动等。 在MFC工程中,你可以将...
17. 单击滚动条的滚动箭头会触发Change事件,导致滚动条状态改变。 18. 构造方法在创建对象时被调用,用于初始化新创建的对象。 19. 创建一个触发器来监控Student_JAVA表的INSERT和UPDATE操作,当grade超过100分时...
这个机制允许对象之间进行通信,当一个对象的某个状态改变时,可以触发另一个对象的动作,无需硬编码依赖关系,增加了代码的可维护性和可扩展性。例如,当用户点击一个按钮,按钮对象会发出一个信号,连接到这个信号...
8. 设计数据访问页时,不能添加选项卡,但可以添加标签、滚动标签和超级链接。 9. Excel2000具备强大的计算和数据分析功能,适用于复杂的公式运算和数据透视分析。 10. 幻灯片是PowerPoint演示文稿的一部分,一张...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
项目中,无状态小部件可能用于定义静态布局或者不需改变的元素,如按钮、标签等。 4. **有状态小部件(StatefulWidget)**:有状态小部件可以更改其状态并通知父组件进行重绘。在旅行应用中,有状态小部件可能用于...
7. **使用DiffUtil**:如果数据源发生改变(例如添加或删除Item),可以使用DiffUtil来高效地计算出差异,只更新必要的Item,避免全量刷新。 综上所述,`CountDownDemo`项目很可能是实现了上述策略的一个实例,演示...