多线程最简单的一种用法就是将互相之间没有资源竞争的代码块同时运行来提高速度。关于实现多线程必须要override run方法,但具体的方法也有几种:
extends Thread
implements Runnable
new Thread的匿名内部类
extends Thread
将你需要进行多线程计算的类扩展自Thread,但这里有个很大的限制就是该类已经继承了别的类就不能使用这个方法。但是它有个好处就是在run中可以访问该类的所有属性。
public class ExtendsThreadTest {
private static Thread thread;
private static Thread thread2;
public static void main(String[] args) {
Student2 stu1 = new Student2("boy", 10);
Student2 stu2 = new Student2("girl", 10);
//启动线程,不能使用run.
stu1.start();
stu2.start();
try {
//等待线程执行完
stu1.join();
stu2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
P.rintln("-----------\nhomework is done!");
}
}
class Student2 extends Thread {
private String name;
private int homeworkNumber;
public Student2(String name, int homeworkNumber) {
this.name = name;
this.homeworkNumber = homeworkNumber;
}
public void doHomework() {
int total = homeworkNumber;
for (int i = total; i >= 0; i--) {
P.rintln("Student: " + name + "'s home work number is " + i);
}
}
@Override
public void run() {
// TODO Auto-generated method stub
doHomework();
}
}
implements Runnable
这个方法比扩展要好一些。在保持其它优点不变的情况下解决了类已经继承的问题。
public class ImlpRunnableTest {
private static Thread thread;
private static Thread thread2;
public static void main(String[] args) {
Student stu1 = new Student("boy", 10);
Student stu2 = new Student("girl", 10);
thread = new Thread(stu1);
thread2 = new Thread(stu2);
//启动线程,不能使用run.
thread.start();
thread2.start();
try {
//等待线程执行完
thread.join();
thread2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
P.rintln("-----------\nhomework is done!");
}
}
class Student implements Runnable {
private String name;
private int homeworkNumber;
public Student(String name, int homeworkNumber) {
super();
this.name = name;
this.homeworkNumber = homeworkNumber;
}
public void doHomework() {
int total = homeworkNumber;
for (int i = total; i >= 0; i--) {
P.rintln("Student: " + name + "'s home work number is " + i);
}
}
@Override
public void run() {
// TODO Auto-generated method stub
doHomework();
}
}
new Thread的匿名内部类
内部类也是可以访问外部的属性和方法的。但这里有个问题,内部类在内部可见,如果应用的线程控制和调度是由其它类实现的,这种情况需要将内部的线程对象返回。
public class NewThreadTest {
private static Thread thread;
private static Thread thread2;
public static void main(String[] args) {
Student3 stu1 = new Student3("boy", 10);
Student3 stu2 = new Student3("girl", 10);
Thread t1 = stu1.doHomework();
Thread t2 = stu2.doHomework();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
P.rintln("-----------\nhomework is done!");
}
}
class Student3 {
private String name;
private int homeworkNumber;
public Student3(String name, int homeworkNumber) {
this.name = name;
this.homeworkNumber = homeworkNumber;
}
public void report(int currentNumberOfHW) {
P.rintln("Student: " + name + "'s home work number is " + currentNumberOfHW);
}
public Thread doHomework() {
Thread t = new Thread(){
public void run() {
int total = homeworkNumber;//直接访问外部类的属性
for (int i = total; i >= 0; i--) {
report(i);
}
}
};
t.start();
return t;
}
}
小结
以上就是最简单的线程使用的3种实现方法。我比较倾向于implements Runnable的方式,限制少而且控制住了耦合度(使用内部类的话,会给用户2个对象)。