java多线程总结
Posted 奔跑de五花肉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程总结相关的知识,希望对你有一定的参考价值。
以前没有写笔记的习惯,现在慢慢的发现及时总结是多么的重要了,呵呵。研二,快要毕业了,要加油了。
这一篇文章主要关于java多线程,主要还是以例子来驱动的。因为讲解多线程的书籍和文章已经很多了,所以我也不好意思多说,呵呵、大家可以去参考一些那些书籍。我这个文章主要关于实际的一些问题。同时也算是我以后复习的资料吧,。呵呵大家多多指教。
同时希望多结交一些技术上的朋友。谢谢。
----------------------------------------------------------------------------------------------------------------------------------------------------
java中的多线程
在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。
对于直接继承Thread的类来说,代码大致框架是:
1
2
3
4
5
6
7
8
9
10
11
12
|
class 类名 extends Thread{ 方法 1 ; 方法 2 ; … public void run(){ // other code… } 属性 1 ; 属性 2 ; … } |
先看一个简单的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/** * @author Rollen-Holt 继承Thread类,直接调用run方法 * */ class hello extends Thread
{ public hello() { } public hello(String name) { this .name
= name; } public void run()
{ for ( int i
= 0 ; i < 5 ;
i++) { System.out.println(name + "运行 " +
i); } } public static void main(String[]
args) { hello h1= new hello( "A" ); hello h2= new hello( "B" ); h1.run(); h2.run(); } private String
name; } |
【运行结果】:
A运行 0
A运行 1
A运行 2
A运行 3
A运行 4
B运行 0
B运行 1
B运行 2
B运行 3
B运行 4
我们会发现这些都是顺序执行的,说明我们的调用方法不对,应该调用的是start()方法。
当我们把上面的主函数修改为如下所示的时候:
1
2
3
4
5
6
|
public static void main(String[]
args) { hello h1= new hello( "A" ); hello h2= new hello( "B" ); h1.start(); h2.start(); } |
然后运行程序,输出的可能的结果如下:
A运行 0
B运行 0
B运行 1
B运行 2
B运行 3
B运行 4
A运行 1
A运行 2
A运行 3
A运行 4
因为需要用到CPU的资源,所以每次的运行结果基本是都不一样的,呵呵。
注意:虽然我们在这里调用的是start()方法,但是实际上调用的还是run()方法的主体。
那么:为什么我们不能直接调用run()方法呢?
我的理解是:线程的运行需要本地操作系统的支持。
如果你查看start的源代码的时候,会发现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public synchronized void start()
{ /** * This method is not invoked for the main method thread or
"system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to
the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus
!= 0 || this !=
me) throw new IllegalThreadStateException(); group.add( this ); start0(); if (stopBeforeStart)
{ stop0(throwableFromStop); } } private native void start0(); |
注意我用红色加粗的那一条语句,说明此处调用的是start0()。并且这个这个方法用了native关键字,次关键字表示调用本地操作系统的函数。因为多线程的实现需要本地操作系统的支持。
但是start方法重复调用的话,会出现java.lang.IllegalThreadStateException异常。
通过实现Runnable接口:
大致框架是:
1
2
3
4
5
6
7
8
9
10
11
12
|
class 类名 implements Runnable{ 方法 1 ; 方法 2 ; … public void run(){ // other code… } 属性 1 ; 属性 2 ; … } |
来先看一个小例子吧:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
/** * @author Rollen-Holt 实现Runnable接口 * */ class hello implements Runnable
{ public hello() { } public hello(String name) { this .name
= name; } public void run()
{ for ( int i
= 0 ; i < 5 ;
i++) { System.out.println(name + "运行 " +
i); } } public static void main(String[]
args) { hello h1= new hello( "线程A" ); Thread demo= new Thread(h1); hello h2= new hello( "线程B" ); Thread demo1= new Thread(h2); demo.start(); demo1.start(); } private String
name; } |
【可能的运行结果】:
线程A运行 0
线程B运行 0
线程B运行 1
线程B运行 2
线程B运行 3
线程B运行 4
线程A运行 1
线程A运行 2
线程A运行 3
线程A运行 4
关于选择继承Thread还是实现Runnable接口?
其实Thread也是实现Runnable接口的:
1
2
3
4
5
6
7
8
|
class Thread implements Runnable
{ //… public void run()
{ if (target != null )
{ target.run(); } } } |
其实Thread中的run方法调用的是Runnable接口的run方法。不知道大家发现没有,Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式。关于代理模式,我曾经写过一个小例子呵呵,大家有兴趣的话可以看一下:http://www.cnblogs.com/rollenholt/archive/2011/08/18/2144847.html
Thread和Runnable的区别:
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/** * @author Rollen-Holt 继承Thread类,不能资源共享 * */ class hello extends Thread
{ public void run()
{ for ( int i
= 0 ; i < 7 ;
i++) { if (count
> 0 ) { System.out.println( "count= " +
count--); } } } public static void main(String[]
args) { hello h1 = new hello(); hello h2 = new hello(); hello h3 = new hello(); h1.start(); h2.start(); h3.start(); } private int count
= 5 ; } |
【运行结果】:
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
大家可以想象,如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享。
我们换为Runnable接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class MyThread implements Runnable{ private int ticket
= 5 ; //5张票 public void run()
{ for ( int i= 0 ;
i<= 20 ; i++) { if ( this .ticket
> 0 ) { System.out.println(Thread.currentThread().getName()+ "正在卖票" + this .ticket--); } } } } public class lzwCode
{ 以上是关于java多线程总结的主要内容,如果未能解决你的问题,请参考以下文章 |