1、线程的创建
java中线程的创建有两种主要方式①创建一个runnable对象r,并实现它的run()方法。然后将该runnable对象r作为参数通过new Thread(r)语句创建新的线程②直接通过new Thread()来创建新线程,但要在其中实现run()方法。(能够这样做是因为Thread类也实现了runnable接口。)
下面还引用《Thinking in Java》中的代码来解释一下,以注释为重点就好,其他多余代码可以忽略!
public class LiftOff implements Runnable //该类实现Runnable接口
{
protected int countDown = 10;
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() { //Runnable必须实现的方法run();
while(countDown-- > 0) {
System.out.print(status());
Thread.yield(); //①
}
}
}
①yield()方法:若有与当前线程优先级相同的线程可运行,那么当前线程进入可运行线程池,一个同优先级的线程运行。如果没有与当前线程优先级相同的线程可运行,那么将什么也不做。
public class BasicThreads {
public static void main(String[] args) {
Thread t = new Thread(new LiftOff());//以runnable对象为参数创建线程
t.start();//start()方法开始线程,即:调用runnable对象的run()方法
System.out.println("Waiting for LiftOff");
}
}
注意,在start开始线程之后,程序会继续向下行语句执行。这是因为main()函数也对应了一个线程。
--------------------------------------------------------以上是线程的第一种创建方式-----------------------------------------------------
--------------------------------------------------------以下是线程的第二种创建方式-----------------------------------------------------
public class ThreadTest2 {
public static void main(String args[ ]){
Hello t1 = new Hello( );
Hello t2 = new Hello( );
t1.start( );
t2.start( );
}
}
class Hello extends Thread{//继承了Thread类的类
int i ;
public void run( ){ //重写run()方法
while( true){
System.out.println("Hello"+i++);
if (i==5) break ;
}
}
}
没什么好说的~~
总结一下常用的Thread构造方法
public Thread(); public Thread(Runnable r); public Thread(Runnable r,String name); public Thread(String name);
--------------------------------------------------------以下是线程的第三种创建方式-----------------------------------------------------
public class SelfManaged implements Runnable {
private int countDown = 5;
private Thread t = new Thread(this);//Thread对象
public SelfManaged() { t.start(); }
public String toString() {
return Thread.currentThread().getName() +
"(" + countDown + "), ";
}
public void run() {
while(true) {
System.out.print(this);
if(--countDown == 0)
return;
}
}
public static void main(String[] args) {
for(int i = 0; i < 5; i++)
new SelfManaged();
}
}
以上代码创建的是一个被称为自管理Runnable的类,不是什么高难度的东西,只是一种编程技巧。类中包含一个Thread的对象,利用this指针传入自身(Runnable对象)进行了初始化。在构造函数中调用start()方法启动线程。这个程序有一个缺陷:当构造器还没结束时,线程可能就已经启动了,这意味着线程可能操作一个不稳定的对象。
补充:创建线程还可以使用内部类的方式。
3、线程休眠
public class SleepingTask extends LiftOff {
public void run() {
try {
while(countDown-- > 0) {
System.out.print(status());
// Old-style:
// Thread.sleep(100);//①
// Java SE5/6-style:
TimeUnit.MILLISECONDS.sleep(100);
}
} catch(InterruptedException e) {
System.err.println("Interrupted");
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++)
exec.execute(new SleepingTask());
exec.shutdown();
}
}
LiftOff是一个Runnable接口。注释②:TimUnit是SE5中引入的显示休眠方式,作用与注释①相同。
注:因为异常不能跨线程传播会main()函数,所以必须在任务内部处理异常。