1. 概述
通过Runable接口实现多线程比继承Thread接口要更实用一些,起码不会占用单继承的名额。
在实现多线程时,还是需要注意同步的问题,下面一个具体的例子。
2. 简单的Runnable接口实现多线程例子
本例子模拟了访客访问网站这个事情。
package org.maoge.thread; //通过Runnable接口实现多线程 public class RunnableDemo implements Runnable{ private int count=0;//系统访问次数 @Override public void run() { count++; System.out.println("第"+count+"位访客来啦!"); } public static void main(String[] args) { RunnableDemo rd=new RunnableDemo(); for(int i=0;i<50;i++){ Thread thread=new Thread(rd); thread.start();//一定要注意不是通过.run()启动线程 } } }
输出如下,有两个问题:1是顺序不对,2是重复(比如第21位访客来啦出现了2次)。
第1位访客来啦! 第33位访客来啦! 第37位访客来啦! 第32位访客来啦! 第38位访客来啦! 第39位访客来啦! 第41位访客来啦! 第43位访客来啦! 第44位访客来啦! 第46位访客来啦! 第31位访客来啦! 第30位访客来啦! 第49位访客来啦! 第29位访客来啦! 第28位访客来啦! 第27位访客来啦! 第26位访客来啦! 第25位访客来啦! 第24位访客来啦! 第23位访客来啦! 第22位访客来啦! 第21位访客来啦! 第21位访客来啦! 第19位访客来啦! 第18位访客来啦! 第17位访客来啦! 第16位访客来啦! 第15位访客来啦! 第14位访客来啦! 第13位访客来啦! 第12位访客来啦! 第11位访客来啦! 第11位访客来啦! 第9位访客来啦! 第8位访客来啦! 第7位访客来啦! 第6位访客来啦! 第5位访客来啦! 第4位访客来啦! 第3位访客来啦! 第2位访客来啦! 第49位访客来啦! 第48位访客来啦! 第48位访客来啦! 第45位访客来啦! 第42位访客来啦! 第40位访客来啦! 第36位访客来啦! 第35位访客来啦! 第34位访客来啦!
简单分析下:
1,顺序不对,这个非常好理解,发起线程后,每个线程都是相对独立的,执行run()方法跟很多因素相关,我们无从分析哪个会执行的快、哪个会慢,所以当然会出现不按顺序的情况。
2,第21位访客,输出了2次。是这样的count=21的机会肯定只有一次,
假设有两个线程a和b,a执行完成后count=20,然后尚未执行输出,此时b线程执行了 count++后count=21,然后此时a、b的输出发生在另外一个线程count++之前,所以发生了重复输出。
3. 利用synchronized实现同步
我们当然是想告诉游客正确的访问次序,所以可以加上synchronized关键字,将run()方法改为同步方法,这样就锁定了这个方法(当一个线程访问时,别的线程不能访问,一个一个来,是以所谓同步)。
代码如下:
package org.maoge.thread; //通过Runnable接口实现多线程 public class RunnableDemo implements Runnable{ private int count=0;//系统访问次数 @Override public synchronized void run() {//通过synchronized实现同步 count++; System.out.println("第"+count+"位访客来啦!"); } public static void main(String[] args) { RunnableDemo rd=new RunnableDemo(); for(int i=0;i<50;i++){ Thread thread=new Thread(rd); thread.start();//一定要注意不是通过.run()启动线程 } } }
输出如下,可见是我们要的结果:
第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位访客来啦! 第31位访客来啦! 第32位访客来啦! 第33位访客来啦! 第34位访客来啦! 第35位访客来啦! 第36位访客来啦! 第37位访客来啦! 第38位访客来啦! 第39位访客来啦! 第40位访客来啦! 第41位访客来啦! 第42位访客来啦! 第43位访客来啦! 第44位访客来啦! 第45位访客来啦! 第46位访客来啦! 第47位访客来啦! 第48位访客来啦! 第49位访客来啦! 第50位访客来啦!