Java技能点--Runnable接口与synchronized

点此查看全部文字教程、视频教程、源代码

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位访客来啦!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员大阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值