您的位置:首页 > 编程语言 > Java开发

【Java学习笔记】14:再谈线程的启动和暂时停止

2017-04-26 11:23 656 查看
线程,即正在执行程序的主体。

在单线程程序里,在某一时间点进行的处理只有一个。也就是说如果在任一时间提出问题“正在执行程序的哪里?”,可以指出程序中的某一点“就是这里”。

实际上严格地说,有些必须的线程是在非Java处理系统上跑,例如垃圾收集时使用的线程、GUI相关线程等。

由一个以上的线程构成的程序是多线程程序,如果这时提问“正在执行程序的哪里?”,就要指出“第一个线程正在执行这里”,而“第二个线程正在执行这里”...

GUI应用程序

几乎所有GUI程序都一定有多线程。如用word编辑一个较大的文本文件,进行查找操作时,屏幕上会出现“停止查找”的按钮,用户随时可停止查找,也就用到了多线程。

①执行查找

②显示按钮,若按下按钮时停止①

这样①专心查找,②专心在GUI上。如果不这样做,难道要在执行查找时不断地用if判断并不断地尝试接受用户的指令吗,这样显然是不合适的。

I/O处理

一般文件和网络的I/O处理比较花费时间,如果在这段时间不执行其它操作,性能就很不好。所以一般把I/O处理和非I/O处理的线程分开,就能利用I/O处理的时间同时进行其他处理了。

*Thread类的run()方法和start()方法

//MyThread.java
package day14;
public class MyThread extends Thread {
public void run()
{
for(int i=0;i<500;i++)
{
System.out.print("线程MyThread!");
}
}
}

//Main.java
package day14;
public class Main {
public static void main(String[] args) {
MyThread t=new MyThread();
t.start();//启动新的线程
for(int i=0;i<500;i++)
System.out.print("主线程!");
}
}


部分运行结果:





线程的启动要用到java.lang.Thread类,这里用自定的MyThread类去继承了它。新启动的线程的操作写在run()方法里。在这里主线程里有两个工作。①启动MyThread线程 ②输出500个“主线程”。start()方法是Thread类的方法,如果调用start()方法就会启动新线程(注意不是run()方法)。调用start()方法时,会有两个操作:①启动新的线程 ②调用run()方法。

从输出中可以看到输出结果交错混合出现。

并发和并行

当有一个以上的线程在操作时,若计算机只有一个中央处理器,根本不可能真正同时进行一个以上的处理,所以上面例子的真正操作情况是:主线程运行一会后停止->MyThread线程运行一会后停止->主线程运行一会后停止->...这样不断切换有操作的线程就称为并发(concurrent)。

如果有一个以上中央处理器的计算机上跑的Java执行处理系统,则线程的操作可能是并行(parallel)而非并发,并行可以真正同时进行一个以上的处理。

并发:



并行:



刚刚的例子是启动线程的一种方法:建立Thread类的子类->在子类中覆写run()方法,线程启动后要做的事都在其中->建立该子类的实例->用这个实例调用start()方法启动线程。

下面是另一个方法。

*实现Runnable接口的类的实例以启动线程

//MyThread.java
package day14;
public class MyThread implements Runnable {
public void run()
{
for(int i=0;i<500;i++)
{
System.out.print("线程MyThread!");
}
}
}

//Main.java
package day14;
public class Main {
public static void main(String[] args) {
MyThread t=new MyThread();//建立实现了Runnable接口的子类的实例
Thread r= new Thread(t);//用这个子类的实例去建立Thread类的实例
r.start();//还是用Thread类的实例启动新的线程
for(int i=0;i<500;i++)
System.out.print("主线程!");
}
}


部分运行结果:



这种方法的流程:建立一个类实现Runnable接口->在这个类中覆写run()方法,线程启动后要做的事都在其中->建立该类的实例->用这个类的实例去建立Thread类的实例->用Thread类的实例调用start()方法以启动线程。

既然能建立Thread类的实例,也就说明Thread类不是抽象类。Thread类本身也实现了Runnable接口,即也实现了run()方法,只不过方法体为空。因此Thread类的run()方法通常都是要被子类覆盖(override)来用。

 

*线程的暂时停止

//Main.java
package day14;
public class Main {
public static void main(String[] args) {
for(int i=0;i<10;i++)
{
System.out.print("主线程!");
try{
Thread.sleep(1000);//当前线程暂停1000ms
}catch(InterruptedException e){
//什么都不做,即生吞异常(这样很不好)
}
}
}
}


运行结果(约每1s跳出一个):



执行Thread类的sleep()方法可以暂时停止当前线程(执行此语句的线程)的执行操作。在这个例子中即是每1秒后输出一个“主线程!”。注意sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。

sleep()方法的调用务必放在try-catch里,因为它可能会抛出一个InterruptedException异常。

实际写程序时sleep()方法用的很少,一般在设计一段时间后关闭对话框或者让用户看到单击按钮时那一瞬间样子时会用到。

 

吃饭。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: