传统的多线程
线程的创建方法: 有两种; 一种是继承Thread类,另一种是实现Runnable接口;下面看例子:
第一种是继承Thread类:
public class MoreClass extends Thread{
@Override
public void run() {
for(int i = 0; i < 20 ; i++){
System.out.println(Thread.currentThread().getName() + ":" +i);
}
}
public static void main(String[] args) {
MoreClass mc = new MoreClass();
MoreClass mc1 = new MoreClass();
mc.start();
mc1.start();
}
}
运行结果:
Thread-0:0
Thread-1:0
Thread-0:1
Thread-1:1
Thread-1:2
Thread-1:3
Thread-1:4
Thread-1:5
Thread-1:6
Thread-1:7
Thread-1:8
Thread-1:9
Thread-1:10
Thread-1:11
Thread-1:12
Thread-1:13
Thread-1:14
Thread-1:15
Thread-1:16
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-1:17
Thread-1:18
Thread-1:19
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-0:10
Thread-0:11
Thread-0:12
Thread-0:13
Thread-0:14
Thread-0:15
Thread-0:16
Thread-0:17
Thread-0:18
Thread-0:19
这里需要说明的是:1.线程的开启不是run()方法,而是start()方法;2.由于计算机的CUP都不一样,所以多次的运行结果基本也都不一样。3.看下Thread的源代码
/**
* If this thread was constructed using a separate
* <code>Runnable</code> run object, then that
* <code>Runnable</code> object's <code>run</code> method is called;
* otherwise, this method does nothing and returns.
* <p>
* Subclasses of <code>Thread</code> should override this method.
*
* @see #start()
* @see #stop()
* @see #Thread(ThreadGroup, Runnable, String)
*/
public void run() {
if (target != null) {
target.run();
}
}
逻辑很简单,如果target == null,那么线程什么也不执行,而我们上面的第一个例子很显然没有定义target和赋值,所以要想看到线程的执行的结果,只能重写父类Thread中的run()方法。
第二种是实现Runnable接口:
public class MoreClass implements Runnable {
@Override
public void run() {
for(int i = 0; i < 20 ; i++){
System.out.println(Thread.currentThread().getName() + ":" +i); //这个方法是获取当前线程额的名字
}
}
public static void main(String[] args) {
MoreClass mc = new MoreClass();
Thread t = new Thread(mc);
t.start();
}
}
运行结果跟例子1 都是一样的基本上,这个方法是实现一个接口。同样看下Thread的源代码
/**
* Allocates a new <code>Thread</code> object. This constructor has
* the same effect as <code>Thread(null, target,</code>
* <i>gname</i><code>)</code>, where <i>gname</i> is
* a newly generated name. Automatically generated names are of the
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
*
* @param target the object whose <code>run</code> method is called.
* @see #Thread(ThreadGroup, Runnable, String)
*/
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Thread 有带参数的构造方法,这个参数就是Runnable对象,而Runnable是一个借口,所以我们要创建一个类去实现这个接口。而想要实现这个接口必须实现这个接口run()方法,简单的理解,这个构造方法是需要传一个Runnabel对象,而我们所要执行的run()方法和其中代码都在Runnable中对象中。
其实上面的两个例子都可以用内部类来实现:
public class OneClass {
public static void main(String args[]){
Thread t1 = new Thread(){
@Override
public void run() {
//实现代码块
}
};
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
//实现代码块
}
});
t1.start();
t2.start();
}
}
这里有两个问题:
1、基本上在创建线程时,都用第二种,第一种用的少,这是为什么呢?
2、其实线程机制并没有提高程序的运行效率,但是为什么又有多线程下载呢?
希望大家给与答案,多多留言,互相进步。 上面的都是基础。希望大神们多多指教,基础牢固了,才能更好地进步。