Java中的多线程 (一)

2014-11-24 09:40:00 · 作者: · 浏览: 5

一、提要
java中的多线程算是java中的一个 很大的难点 ,虽然 看了 很多书 ,相信对于 很多 接触 java不够 深的人来说 ,多线程永远都是心中的痛!
今天我们 就 通过大量的 例子 来 彻底把它征服 .


二、Runable接口
实现 Runable接口 是 实现多线程 的 一种方法。看例子
[java]
package thread;
public class LiftOff implements Runnable {
protected int countDown = 10; // Default
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {}
public LiftOff(int countDown) {
this.countDown = countDown;
}
public String status() {
return "#" + id + "(" +
(countDown > 0 countDown : "Liftoff!") + "), ";
}
public void run() {
while(countDown-- > 0) {
System.out.print(status());
Thread.yield();
}
}
}

package thread;
public class LiftOff implements Runnable {
protected int countDown = 10; // Default
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {}
public LiftOff(int countDown) {
this.countDown = countDown;
}
public String status() {
return "#" + id + "(" +
(countDown > 0 countDown : "Liftoff!") + "), ";
}
public void run() {
while(countDown-- > 0) {
System.out.print(status());
Thread.yield();
}
}
}

这个类的实现了 一个线程 :implements了Runable接口 ,实现了 run方法。
通常情况下,run方法中都会有意个循环 ,直到任务结束的时候才会跳出来。
线程的主要任务是循环十次,每次打印出 终端 状态。Thread.yield()的作用是如果线程队列中有线程等待,则阻塞自己,
将资源 交给 下一个等待的线程。


在main函数中 调用如下:
[java]
package thread;
public class Main {
public static void main(String[] arges)
{
LiftOff tmp=new LiftOff();
tmp.run();
System.out.println("Waiting for LiftOff");
}
}

package thread;
public class Main {
public static void main(String[] arges)
{
LiftOff tmp=new LiftOff();
tmp.run();
System.out.println("Waiting for LiftOff");
}
}


将类型初始化实例时候 ,直接 调用run方法,线程就会开始运行。
运行结果:
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!), Waiting for LiftOff
这里实际上并没有线程的概念,只是用到了一些简单的函数调用。
真正的线程需要将Runable装到一个Thread中去。


三、Thread实例
传统的使用Runable对象的方法就是把它作为一个参数传给Thread的构造函数作为参数,然后调用Thread的start()方法来启动线程。
start()方法对Runale进行 了 一些 必要的初始化,然后调用Runable的run方法。
将原main函数改写如下:
[java]
package thread;
public class Main {
public static void main(String[] arges)
{
Thread t = new Thread(new LiftOff());
t.start();
System.out.println("Waiting for LiftOff");


}
}

package thread;
public class Main {
public static void main(String[] arges)
{
Thread t = new Thread(new LiftOff());
t.start();
System.out.println("Waiting for LiftOff");


}
}

运行结果:
Waiting for LiftOff
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!),


运行的结果和之前的例子类似,但“Waiting for LiftOff“出现的位置不同了。
原理:在程序的第五行声明了一个线程,并初始化,一个LiftOff对象作为参数传进去。
第六行通过线程调用启动了t线程,但main线程还可以继续干自己的事,cpu给的时间片还没用完,于是“Waiting for LiftOff”就先被打印出来了,之后时间片被用完了,资源交给t线程,运行的内容被打印出来了。
下面是在main中启动多个线程:
[java]
package thread;
public class Main {


public static void main(String[] arges)
{
for(int i = 0; i < 5; i++)
new Thread(new LiftOff()).start();
System.out.println("Waiting for LiftOff");
}
}

package thread;
public class Main {


public static void main(String[] arges)
{
for(int i = 0; i < 5; i++)
new Thread(new LiftOff()).start();
System.out.println("Waiting for LiftOff");
}
}

修改一下LiftOff类:
[java]
package thread;
public class LiftOff implements Runnable {
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {}
public void run() {
System.out.println("startThreadId: " + id);
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
System.out.println("endTHreadId: " + id);
}
}

package thread;
public class LiftOff implements Runnable