程序与进程
程序:一段静态的代码。
进程:程序的一次动态执行过程,它对应从代码加载、执行到执行完毕的一个完整过程。
进程也称任务,支持多个进程同时执行的OS就被称为多进程OS或多任务OS。
在一个程序内部也可以实现多个任务并发执行,其中每个任务称为线程。
线程是比进程更小的执行单位,它是在一个进程中独立的控制流,即程序内部的控制流。
特点:线程不能独立运行,必须依赖于进程,在进程中运行。
每个程序至少有一个线程称为主线程。
单线程:只有一条线程的进程称为单线程
多线程:有不止一个线程的进程称为多线程
开启多线程的优点和缺点
提高界面程序响应速度。通过使用线程,可以将需要大量时间完成的流程在后台启动单独的线程完成,提高前台界面的相应速度。
充分利用系统资源,提高效率。通过在一个程序内部同时执行多个流程,可以充分利用CPU等系统资源,从而最大限度的发挥硬件的性能。
当程序中的线程数量比较多时,系统将花费大量的时间进行线程的切换,这反而会降低程序的执行效率。但是,相对于优势来说,劣势还是很有限的,所以现在的项目开发中,多线程编程技术得到了广泛的应用。
在实现线程编程时,首先需要让一个类具备多线程的能力,继承Thread类或实现Runnable接口的类具备多线程的能力,然后创建线程对象,调用对应的启动线程方法即可实现线程编程。
在一个程序中可以实现多个线程,多线程编程指在同一个程序中启动了两个或两个以上的线程。
在实际实现线程时,Java语言提供了三种实现方式:
继承Thread类
实现Runnable接口
使用Timer和TimerTask组合
继承Thread线程类实现多线程
java.lang包中提供了一个专门的线程类(Thread),在该类中封装了许多对线程进行调度和处理的方法。如果一个类继承了Thread类,则该类就具备了多线程的能力,可以多线程的方式执行。
class MyThread extends Thread{
public void run(){
//线程体
}
}
注意:
线程的特性:随机性,系统在执行多线程程序时只保证线程是交替执行的,至于哪个线程先执行哪个线程后执行,则无法获得保证,需要书写专门的代码才可以保证执行的顺序。
对于同一个线程类,也可以启动多个线程。
Thread2 t2 = new Thread2(); t2.start();
Thread2 t3 = new Thread2(); t3.start();
同一个线程不能启动两次,例如
Thread2 t2 = new Thread2();
t2.start(); t2.start(); //错误
当自定义线程中的run方法执行完成以后,则自定义线程自然死亡。而对于系统线程来说,只有当main方法执行结束,而且启动的其它线程都结束以后,才会结束。当系统线程执行结束以后,程序的执行才真正结束。
实现Runable接口
多线程对象实现java.lang.Runnable接口并且在该类中重写Runnable接口的run方法。
好处:实现Runable接口的方法避免了单继承的局限性。
使用实现Runable接口的方式实现多线程。
class MyThread2 implements Runable{
publicvoid run(){} //重写Runable接口中的run()方法
}
MyThread2 mt1=new MyThread2();
Thread t1=new Thread(mt1);
t1.start();
实现数字时钟
package com.hbsi;
importjava.util.*;
import javax.swing.*;
public class TestClock {
publicstatic void main(String[] args) {
JFramejf=new JFrame();
JLabelclock=new JLabel();
clock.setHorizontalAlignment(JLabel.CENTER);
jf.add(clock);
jf.setSize(250,80);
jf.setLocation(500,300);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
MyThreadt=new MyThread(clock);
t.start();
}
}
class MyThread extends Thread{
privateJLabel clock;
publicMyThread(JLabel clock){
this.clock=clock;
}
publicvoid run(){
while(true){
clock.setText(getTime());
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){}
}
}
publicString getTime(){
//Calendarc=Calendar.getInstance();
Calendarc=new GregorianCalendar();
Stringtime=c.get(Calendar.YEAR)+"年"+(c.get(Calendar.MONTH)+1)+"月"+c.get(Calendar.DATE)+"日"+" ";
inth=c.get(Calendar.HOUR);
intm=c.get(Calendar.MINUTE);
ints=c.get(Calendar.SECOND);
Stringph=h<10?"0":"";
Stringpm=m<10?"0":"";
Stringps=s<10?"0":"";
time+= ph+h+":"+pm+m+":"+ps+s;
returntime;
}
}
实现自动变换广告条
package com.hbsi;
importjava.awt.Font;
import javax.swing.*;
public class Test2 extends JFrameimplements Runnable{
/**
* @param args
*/
JLabellabel;
String[]content={"河北软件职业技术学院","优快云乐知学院欢迎您","2011优快云Java方向"};
inti=0;
publicTest2(){
label=newJLabel(content[0]);
Font f=new Font("宋体",Font.BOLD,16);
label.setFont(f);
JPanelp=new JPanel();
p.add(label);
add(p);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300,300);
setLocation(400,400);
setVisible(true);
}
publicstatic void main(String[] args) {
Test2tt=new Test2();
Threadt=new Thread(tt);
t.start();
}
@Override
publicvoid run() {
while(true){
display();
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
publicvoid display(){
label.setText(content[i]);
i++;
if(i>=3)
i=0;
}
}
多线程的实现过程
1.实现java.lang.Runnable接口;
2.重写Runnable接口的run方法;
3.创建Runnable接口的子类对象;
4.创建Thread类的对象,并将Runnable接口的子类对象作为参数传递给Thread类的构造方法,最后调用Thread对象的start方法即可启动线程。
Runnable1 r1 = new Runnable1();
Thread t1 = new Thread(r1);
t1.start();