01____实现多线程的方式
来源:互联网 发布:linux 解包 编辑:程序博客网 时间:2024/05/19 16:49
创建多线程有两种方式,一种是继承Thread类,一种是实现Runable接口。
具体代码为:
这两种方式生成了一个Thread的子类,这两种方式内部都有两条线程,一条是主线程,一条是Test内的run()方法。
观察Thread类的源码就会发现,其实Thread类继承了Runnable接口。
通过start()方法启动线程。start()方法是开始线程的方法,会自动调用线程的run()方法。
run()是Thread的具体实现。
通过实现Runnable接口实现多线程。
打印结果:
Thread-1出售第1张票,还剩9张票
Thread-0出售第1张票,还剩9张票
Thread-1出售第2张票,还剩8张票
Thread-0出售第2张票,还剩8张票
Thread-1出售第3张票,还剩7张票
Thread-0出售第3张票,还剩7张票
Thread-0出售第4张票,还剩6张票
Thread-0出售第5张票,还剩5张票
Thread-0出售第6张票,还剩4张票
Thread-0出售第7张票,还剩3张票
Thread-0出售第8张票,还剩2张票
Thread-0出售第9张票,还剩1张票
Thread-0出售第10张票,还剩0张票
Thread-1出售第4张票,还剩6张票
Thread-1出售第5张票,还剩5张票
Thread-1出售第6张票,还剩4张票
Thread-1出售第7张票,还剩3张票
Thread-1出售第8张票,还剩2张票
Thread-1出售第9张票,还剩1张票
Thread-1出售第10张票,还剩0张票
从打印结果来看,自己卖自己的,并没有实现数据的共享。
2.用Runnable实现:
Thread-0出售第1张票,还剩9张票
Thread-1出售第1张票,还剩9张票
Thread-0出售第2张票,还剩8张票
Thread-1出售第2张票,还剩7张票
Thread-0出售第3张票,还剩6张票
Thread-0出售第4张票,还剩4张票
Thread-1出售第3张票,还剩5张票
Thread-0出售第5张票,还剩3张票
Thread-1出售第4张票,还剩2张票
Thread-1出售第5张票,还剩0张票
Thread-0出售第6张票,还剩1张票
由此可见,继承Runnable确实实现了数据的共享。
执行结果:
sub
sub
sub
sub
...
此时的会一直打印sub,并不会打印main,说明值执行了run()方法。此时run方法做为一个普通方法被执行。
main
main
sub
main
sub
sub
.....
此时run中的逻辑代码和run方法外的逻辑代码同时被执行。实现了多线程。
继承Thread类:
java可以通过继承Thread类的方式实现多线程。具体代码为:
public class Test{ public static void main(String [] args){ //直接new一个线程 Thread thread01 = new Thread(){ @Override public void run() { //实现代码 } }; thrad01.start(); }}
//类继承Threadpublic class Test extends Thread{ @Override public void run() { //方法体 } public static void main(String[] args) { Test test = new Test();//Test是多线程的子类,直接new //执行多线程 test.start(); } }
这两种方式生成了一个Thread的子类,这两种方式内部都有两条线程,一条是主线程,一条是Test内的run()方法。
观察Thread类的源码就会发现,其实Thread类继承了Runnable接口。
通过start()方法启动线程。start()方法是开始线程的方法,会自动调用线程的run()方法。
run()是Thread的具体实现。
实现Runnable接口:
通过实现Runnable接口实现多线程。
具体代码为:
public class Test { public static void main(String[] args) { //new一个线程,线程内new一个runnable方法。 Thread thread = new Thread(new Runnable() { public void run() { //代码 } }); thread.start(); //主线程逻辑代码 }}
public class Test implements Runnable{ public void run() { //逻辑代码 } public static void main(String[] args) { Test test = new Test(); new Thread(test).start();//Test是实例,new一个多线程对象,把他放进去。 //主线程逻辑代码 }}
此时主线程的逻辑代码就会和run()方法内的逻辑代码同时执行,实现了多线程。
实现Runable方法可实现数据的共享,具体例子:
数据共享:
线程数据共享通过卖票系统就能体现出来。
1.先用Thread方法实现:public class SellTicketTest extends Thread{ public int ticket = 10; public void run() { for (int i = 1; i < 100; i++) { if (ticket > 0) { System.out.println(Thread.currentThread().getName()+"出售第" + i + "张票,还剩" + --ticket +"张票"); } } }; public static void main(String[] args) { SellTicketTest s1 = new SellTicketTest();//SellTickeTest是Thread的子类,直接new就可以。 s1.start(); SellTicketTest s2 = new SellTicketTest(); s2.start(); }}
打印结果:
Thread-1出售第1张票,还剩9张票
Thread-0出售第1张票,还剩9张票
Thread-1出售第2张票,还剩8张票
Thread-0出售第2张票,还剩8张票
Thread-1出售第3张票,还剩7张票
Thread-0出售第3张票,还剩7张票
Thread-0出售第4张票,还剩6张票
Thread-0出售第5张票,还剩5张票
Thread-0出售第6张票,还剩4张票
Thread-0出售第7张票,还剩3张票
Thread-0出售第8张票,还剩2张票
Thread-0出售第9张票,还剩1张票
Thread-0出售第10张票,还剩0张票
Thread-1出售第4张票,还剩6张票
Thread-1出售第5张票,还剩5张票
Thread-1出售第6张票,还剩4张票
Thread-1出售第7张票,还剩3张票
Thread-1出售第8张票,还剩2张票
Thread-1出售第9张票,还剩1张票
Thread-1出售第10张票,还剩0张票
从打印结果来看,自己卖自己的,并没有实现数据的共享。
2.用Runnable实现:
public class SellTicketTest implements Runnable{ public int ticket = 10; public void run() { for (int i = 1; i < 100; i++) { if (ticket > 0) { System.out.println(Thread.currentThread().getName()+"出售第" + i + "张票,还剩" + --ticket + "张票"); } } }; public static void main(String[] args) { SellTicketTest s = new SellTicketTest(); Thread t1 = new Thread(s);//SellTickeTest是Thread的实例,new一个Thread,放进去。 t1.start(); Thread t2 = new Thread(s); t2.start(); }}输出结果:
Thread-0出售第1张票,还剩9张票
Thread-1出售第1张票,还剩9张票
Thread-0出售第2张票,还剩8张票
Thread-1出售第2张票,还剩7张票
Thread-0出售第3张票,还剩6张票
Thread-0出售第4张票,还剩4张票
Thread-1出售第3张票,还剩5张票
Thread-0出售第5张票,还剩3张票
Thread-1出售第4张票,还剩2张票
Thread-1出售第5张票,还剩0张票
Thread-0出售第6张票,还剩1张票
由此可见,继承Runnable确实实现了数据的共享。
start()和run()的区别:
start():
只有通过start启动线程才能实现多线程,此时无需等待run方法体类的方法与run方法外的代码同时运行。通过调用Thread类的start()方法来启动一个线程,这是只是告诉cpu这个进程进入就绪状态。等待cpu分配给时间片。
得到时间片开始执行run()方法。
run():
run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
run()和start()例子:
public class Test extends Thread{ @Override public void run() { while(true){ System.out.println("sub"); } } public static void main(String[] args) { Test test = new Test(); test.run();//执行的run()方法 while(true){ System.out.println("main"); } }}
执行结果:
sub
sub
sub
sub
...
此时的会一直打印sub,并不会打印main,说明值执行了run()方法。此时run方法做为一个普通方法被执行。
public class Test extends Thread{ @Override public void run() { while(true){ System.out.println("sub"); } } public static void main(String[] args) { Test test = new Test(); test.start();//执行的start()方法 while(true){ System.out.println("main"); } }}打印结果:
main
main
sub
main
sub
sub
.....
此时run中的逻辑代码和run方法外的逻辑代码同时被执行。实现了多线程。
0 0
- 01____实现多线程的方式
- 多线程的实现方式
- 多线程的实现方式
- 多线程的实现方式
- 多线程的实现方式
- Java多线程____一个简单的多线程demo
- java实现多线程的方式
- java多线程的实现方式
- Java多线程的实现方式
- Java多线程的实现方式
- php实现多线程的方式
- java 实现多线程的方式
- 多线程程序实现的方式
- Android多线程的实现方式
- Java实现多线程的方式
- Java 实现多线程的方式
- 多线程同步实现的方式
- UE4--多线程的实现方式
- RTEMS 文件系统设计指南
- Java容器集合类的区别用法
- ARM内存映射
- 自定义竖状字母条
- 【深度优先搜索算法】
- 01____实现多线程的方式
- Poj 2386 Lake Counting
- "=="和equals方法究竟有什么区别?
- C#学习之列表
- 谷歌-SEO
- windows系统下openssl的编译
- ubuntu 13.1o 使用root帐号登录X
- 基于插件开发的Android实现流程
- RFT中发送键盘按键 - inputChars inputkeys