java支持内置的多线程机制。Java语言包中的Runnable接口约定线程执行方法,Thread类提供创建、管理和控制线程对象的方法。
Runnable接口
Runnable接口中只声明了一个run()方法,声明如下:
public interface Runnable
{
public abstract void run();
}
Runnable接口约定抽象方法run()是线程的执行方法,一个线程对象必须实现run()方法以描述线程的所有活动及执行的操作,以实现的run()方法称为该线程对象的线程体。
实例:
public class NumberRunnable implements Runnable
{
private int first;
public NumberRunnable(int first)
{
this.first = first;
}
public void run() //线程体,实现Runnable接口
{
System.out.println();
for (int i=first; i<50; i+=2)
System.out.print(i+" ");
System.out.println("结束!");
}
public static void main(String args[])
{
NumberRunnable target = new NumberRunnable(1); //创建具有线程体的目标对象
Thread thread_odd = new Thread(target,"奇数线程"); //以目标对象创建线程对象
thread_odd.start();
new Thread(new NumberRunnable(2),"偶数线程").start();
}
}
/*
程序运行结果如下:
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34
36 38 40 42 44 46 48 结束!
31 33 35 37 39 41 43 45 47 49 结束!
*/
Thread线程类
Thread类具有封装线程对象的能力,它声明创建、管理和控制线程对象的方法。Thread类声明实现Runnale接口。部分声明方法如下:
public class Thread extends Object implements Runnable
{
public void start();//开始执行线程的run方法
public void interrupt();//中断线程
public static Thread currentThread();//获得当前线程实例
public final void setName(String);//设置线程的名称
}
实例:
public class NumberThread extends Thread
{
private int first; //序列初值
public NumberThread(String name, int first) //name指定线程名,first指定序列初值
{
super(name);
this.first = first;
}
public void run() //线程体,覆盖Thread的run()
{
System.out.print("\n"+this.getName()+": ");
for (int i=first; i<50; i+=2)
System.out.print(i+" ");
System.out.println(this.getName() +"结束!");
}
public static void main(String args[])
{
System.out.println("currentThread="+Thread.currentThread().getName()); //输出当前线程对象名
System.out.println("main Priority="+Thread.currentThread().getPriority()); //输出当前线程对象的优先级
NumberThread thread_odd = new NumberThread("奇数线程",1); //创建线程对象
NumberThread thread_even = new NumberThread("偶数线程",2);
thread_odd.setPriority(MIN_PRIORITY);//MAX_PRIORITY);//10); //设置优先级为最高
thread_odd.start(); //启动线程对象
thread_even.start();
System.out.println("activeCount="+Thread.activeCount()); //输出当前活动线程数
System.out.println("thread_odd Priority="+thread_odd.getPriority()); //输出当前线程对象的优先级
}
}
/*
程序运行结果如下:
currentThread=main
activeCount=3
main Priority=5
奇数线程: 1 3 5 7 9 11 13 15 17 19 21 23 25 27
偶数线程: 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34
36 38 40 42 44 46 48 偶数线程结束!
29 31 33 35 37 39 41 43 45 47 49 奇数线程结束!
*/
滚动字代码:
import java.awt.Event;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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[]){
super("滚动字");
this.setBounds(300,300,400,240);
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);
}
}
/**
* 自定义面板类,私有内部类,实现动作事件监听接口和线程接口
* @author 叶和亚
*
*/
private class RollbyJPanel extends JPanel implements ActionListener,Runnable{
JTextField text_word,text_sleep,text_state;
JButton button_start,button_interrupt;//启动按钮、中断按钮
Thread thread;//线程对象
int sleeptime;//线程睡眠时间
RollbyJPanel(String text){
this.setLayout(new GridLayout(2, 1));//两行一列
text_word=new JTextField(String.format("%115s", text)); //text后加空格字符串
this.add(text_word);//滚动字文本
JPanel panel_sub=new JPanel();
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 =new Thread(this);//创建线程对象,目标对象是当前对象
button_interrupt.setEnabled(false);//设置中断按钮为无效状态
panel_sub.add(new JLabel("state"));
text_state=new JTextField(""+thread.getState(),10);//线程状态文本行
//get State()返回线程当前的状态,有四种状态
text_state.setEditable(false);
panel_sub.add(text_state);
}
public void run() {
while(true){//线程活动且没中断时//thread_rollby.isAlive() && !thread_rollby.isInterrupted())
try {
String str=text_word.getText();
text_word.setText(str.substring(1)+str.substring(0, 1));//实现字符串移动!!
Thread.sleep(sleeptime);
} catch (InterruptedException e) {
break;//退出循环
}
}
}
public void actionPerformed(ActionEvent ev) {
if(ev.getSource()==button_start){
thread=new Thread(this);
thread.start();
text_state.setText(""+thread.getState());//显示线程状态
button_start.setEnabled(false);
button_interrupt.setEnabled(true);
}
if(ev.getSource()==button_interrupt){//单机中断线程
thread.interrupt();//设置当前线程对象中断标记
text_state.setText(""+thread.getState());
button_start.setEnabled(true);
button_interrupt.setEnabled(false);
}
if(ev.getSource()==text_sleep){//单机睡眠时间文本行时
try{
sleeptime=Integer.parseInt(text_sleep.getText());
}catch ( NumberFormatException e) {
JOptionPane.showMessageDialog(this, "\""+text_sleep.getText()+"\" 不能转换成整数,请重新输入!");
}
}
}
}
public static void main(String arg[])
{
String texts[]={"Welcome","Hello","Rollby"};
new WelcomeJFrame(texts);
}
}
substring()用法
public String substring (int beginIndex , int endIndex)
第一个beginIndex为开始的索引,对应String数字中的开始位置,
第二个endIndex是截止的索引位置,对应String中的结束位置
1、取得的字符串长度为:endIndex - beginIndex;
2、从beginIndex开始取,到endIndex结束,从0开始数,其中不包括endIndex位置的字符
如:
“hamburger”.substring(4, 8) returns “urge”
“smiles”.substring(1, 5) returns “mile”
注意:substring(1)截取掉从首字母起长度为1的字符串。
getSource()和getActionCommand()的区别
e.getSource() 返回的当前动作所指向的对象,包含对象的所有信息
e.getActionCommand() 返回的是当前动作指向对象的名称