如何实现多线程
Java实现多线程主要有以下两种方式:
(1)继承Thread类
(2)实现Runnable接口
注意:无论使用哪种方法必须重写run方法。
Oracle的官方文档解释如下:
There are two ways to create a new thread of execution. One is to declare a class to be a subclass of Thread. This subclass should override the run method of class Thread.
有两种方式创建一个新线程的执行。其中一个是声明Thread类的子类。这个子类必须重写Thread类里的run方法。
The other way to create a thread is to declare a class that implements the Runnable interface. That class then implements the run method. An instance of the class can then be allocated, passed as an argument when creating Thread, and started.
另外创建一个线程的方式是声明一个类实现Runnable接口。这个类之后也要实现run方法。之后,可以创建一个这个类的实例,并在创建Thread对象时把这个参数传入。
方法一代码1:
public class MyThread extends Thread //实现多线程的方法一:继承Thread类
{
String name;
public MyThread(String name)
{
this.name=name;
}
@Override
public void run()
{
for(int i=0;i<1000;i++)
{
System.out.println(name+":"+i);
}
}
public static void main(String[]args)
{
MyThread t1= new MyThread("Thread A");
MyThread t2= new MyThread("Thread B");
t1.start();
t2.start();
}
}
运行结果:可以看见,t1,t2两个线程是同时执行的。
Thread A:0
Thread B:0
Thread A:1
Thread B:1
Thread A:2
Thread B:2
Thread A:3
Thread B:3
Thread A:4
Thread B:4
Thread A:5
Thread B:5
Thread A:6
Thread B:6
Thread A:7
Thread B:7
Thread A:8
Thread B:8
Thread A:9
Thread B:9
Thread A:10
Thread B:10
Thread A:11
Thread B:11
Thread A:12
Thread B:12
Thread A:13
Thread B:13
Thread A:14
Thread B:14
Thread A:15
Thread B:15
Thread A:16
Thread B:16
Thread A:17
Thread B:17
Thread A:18
Thread B:18
Thread A:19
Thread B:19
Thread A:20
Thread B:20
Thread A:21
Thread B:21
Thread A:22
Thread B:22
Thread A:23
Thread B:23
Thread A:24
Thread B:24
Thread A:25
Thread B:25
Thread A:26
Thread B:26
Thread A:27
Thread B:27
Thread A:28
Thread B:28
Thread A:29
Thread B:29
Thread A:30
Thread B:30
Thread A:31
Thread B:31
Thread A:32
Thread B:32
Thread A:33
Thread B:33
Thread A:34
Thread B:34
Thread A:35
Thread B:35
Thread A:36
Thread B:36
Thread A:37
Thread B:37
Thread A:38
Thread B:38
Thread A:39
Thread B:39
Thread A:40
Thread B:40
Thread A:41
Thread B:41
Thread A:42
Thread B:42
Thread A:43
Thread B:43
Thread A:44
Thread B:44
Thread A:45
Thread B:45
Thread A:46
Thread B:46
Thread A:47
Thread B:47
Thread A:48
Thread A:49
Thread A:50
Thread A:51
Thread A:52
Thread A:53
Thread A:54
Thread A:55
Thread A:56
Thread A:57
Thread A:58
Thread A:59
Thread A:60
Thread A:61
Thread A:62
Thread A:63
Thread A:64
Thread A:65
Thread A:66
Thread A:67
Thread A:68
Thread A:69
Thread A:70
Thread A:71
Thread A:72
Thread A:73
Thread A:74
Thread A:75
Thread A:76
Thread A:77
Thread A:78
Thread A:79
Thread B:48
Thread A:80
Thread B:49
Thread A:81
Thread B:50
Thread A:82
Thread B:51
Thread A:83
Thread B:52
Thread A:84
Thread B:53
Thread A:85
Thread B:54
Thread A:86
Thread B:55
Thread A:87
Thread B:56
Thread A:88
Thread B:57
Thread B:58
Thread B:59
Thread B:60
Thread B:61
Thread B:62
Thread B:63
Thread B:64
Thread B:65
Thread B:66
Thread B:67
Thread B:68
Thread B:69
Thread A:89
Thread A:90
Thread A:91
Thread A:92
Thread A:93
Thread A:94
Thread A:95
Thread A:96
Thread A:97
Thread A:98
Thread A:99
Thread B:70
Thread B:71
Thread B:72
Thread B:73
Thread B:74
Thread B:75
Thread B:76
Thread B:77
Thread B:78
Thread B:79
Thread B:80
Thread B:81
Thread B:82
Thread B:83
Thread B:84
Thread B:85
Thread B:86
Thread B:87
Thread B:88
Thread B:89
Thread B:90
Thread B:91
Thread B:92
Thread B:93
Thread B:94
Thread B:95
Thread B:96
Thread B:97
Thread B:98
Thread B:99
方法二代码2:
public class MyRunnable implements Runnable //通过实现Runnable接口实现多线程
{
Thread t1= new Thread();
String name;
public MyRunnable(String name )
{
this.name = name ;
}
public void run(){
for(int i=0;i<100;i++)
{
System.out.println(name+":"+i);
}
}
public static void main(String[]args)
{
Thread t1= new Thread(new MyRunnable("A"));
MyRunnable r2 = new MyRunnable("B");
Thread t2= new Thread(r2);
t1.start();
t2.start();
}
}
运行结果:
A:0
B:0
A:1
B:1
A:2
B:2
A:3
B:3
B:4
B:5
B:6
A:4
A:5
A:6
A:7
A:8
B:7
A:9
B:8
A:10
B:9
A:11
B:10
B:11
B:12
B:13
B:14
B:15
B:16
B:17
B:18
B:19
B:20
B:21
B:22
B:23
B:24
B:25
B:26
B:27
B:28
B:29
B:30
B:31
B:32
B:33
B:34
B:35
B:36
B:37
B:38
B:39
A:12
B:40
A:13
B:41
B:42
B:43
B:44
B:45
B:46
B:47
B:48
B:49
B:50
B:51
B:52
B:53
B:54
B:55
B:56
B:57
A:14
A:15
A:16
B:58
A:17
B:59
A:18
B:60
A:19
B:61
A:20
B:62
A:21
B:63
B:64
A:22
B:65
A:23
B:66
A:24
B:67
A:25
B:68
A:26
B:69
A:27
B:70
A:28
B:71
A:29
B:72
A:30
B:73
A:31
B:74
A:32
B:75
A:33
B:76
A:34
B:77
A:35
B:78
A:36
B:79
A:37
B:80
A:38
B:81
A:39
B:82
A:40
B:83
A:41
B:84
A:42
B:85
A:43
B:86
A:44
B:87
A:45
B:88
A:46
B:89
A:47
B:90
A:48
B:91
A:49
B:92
A:50
B:93
A:51
B:94
A:52
B:95
A:53
B:96
A:54
B:97
B:98
B:99
A:55
A:56
A:57
A:58
A:59
A:60
A:61
A:62
A:63
A:64
A:65
A:66
A:67
A:68
A:69
A:70
A:71
A:72
A:73
A:74
A:75
A:76
A:77
A:78
A:79
A:80
A:81
A:82
A:83
A:84
A:85
A:86
A:87
A:88
A:89
A:90
A:91
A:92
A:93
A:94
A:95
A:96
A:97
A:98
A:99
问题:为什么要在主程序中调用start方法,而不是run方法?
oracle的官方文档对run和start方法解释如下:
run()
If this thread was constructed using a separate Runnable run object, then that Runnable object’s run method is called; otherwise, this method does nothing and returns.
start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
假设我们在代码2的main方法中作如下改动:
public static void main(String[]args)
{
MyRunnable r1 = new MyRunnable("A");
MyRunnable r2 = new MyRunnable("B");
r1.run();
r2.run();
}
当我们执行这个程序时,发现:
A:0
A:1
A:2
A:3
A:4
A:5
A:6
A:7
A:8
A:9
A:10
A:11
A:12
A:13
A:14
A:15
A:16
A:17
A:18
A:19
A:20
A:21
A:22
A:23
A:24
A:25
A:26
A:27
A:28
A:29
A:30
A:31
A:32
A:33
A:34
A:35
A:36
A:37
A:38
A:39
A:40
A:41
A:42
A:43
A:44
A:45
A:46
A:47
A:48
A:49
A:50
A:51
A:52
A:53
A:54
A:55
A:56
A:57
A:58
A:59
A:60
A:61
A:62
A:63
A:64
A:65
A:66
A:67
A:68
A:69
A:70
A:71
A:72
A:73
A:74
A:75
A:76
A:77
A:78
A:79
A:80
A:81
A:82
A:83
A:84
A:85
A:86
A:87
A:88
A:89
A:90
A:91
A:92
A:93
A:94
A:95
A:96
A:97
A:98
A:99
B:0
B:1
B:2
B:3
B:4
B:5
B:6
B:7
B:8
B:9
B:10
B:11
B:12
B:13
B:14
B:15
B:16
B:17
B:18
B:19
B:20
B:21
B:22
B:23
B:24
B:25
B:26
B:27
B:28
B:29
B:30
B:31
B:32
B:33
B:34
B:35
B:36
B:37
B:38
B:39
B:40
B:41
B:42
B:43
B:44
B:45
B:46
B:47
B:48
B:49
B:50
B:51
B:52
B:53
B:54
B:55
B:56
B:57
B:58
B:59
B:60
B:61
B:62
B:63
B:64
B:65
B:66
B:67
B:68
B:69
B:70
B:71
B:72
B:73
B:74
B:75
B:76
B:77
B:78
B:79
B:80
B:81
B:82
B:83
B:84
B:85
B:86
B:87
B:88
B:89
B:90
B:91
B:92
B:93
B:94
B:95
B:96
B:97
B:98
B:99
这与调用普通的方法没有区别,t1,t2调用的run方法并不是同时执行的。
但是,从官方文档可以看到,当我们调用start方法时,Java虚拟机会自动调用run方法。
附录:
Runnable接口的官方说明:
The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. The class must define a method of no arguments called run.
*实现了Runnable接口必须定义无参的run方法
This interface is designed to provide a common protocol for objects that wish to execute code while they are active. For example, Runnable is implemented by class Thread. Being active simply means that a thread has been started and has not yet been stopped.
In addition, Runnable provides the means for a class to be active while not subclassing Thread. A class that implements Runnable can run without subclassing Thread by instantiating a Thread instance and passing itself in as the target. In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.
*当你只想重写run方法时,建议使用一个类实现Runnable接口来实现多线程,这非常重要,因为一个类不应该成为子类除非程序员打算改变改变或增强这个类的一些基本的操作。
另外附上Thread比较基础常用的构造方法。
Thread()
Allocates a new Thread object.
Thread(Runnable target)
Allocates a new Thread object.
Thread(Runnable target, String name)
Allocates a new Thread object.
Thread(String name)
Allocates a new Thread object.