Java Tread多线程(2)多线程安全问题

作者 :卿笃军

原文地址:http://blog.csdn.net/qingdujun/article/details/39348093

本文演示,Tread多线程安全问题,以及一种解决多线程安全方式(线程同步)。

1)一个线程不安全的Demo

2)线程同步

一、小Demo演示引出线程安全问题:

package thread.runable1.qdj;
//1.定义类实现Runnable接口
class RunDemo1 implements Runnable
{
	private int x = 5;
	//2.覆盖Runnable接口中的run方法
	//将线程代码存放在run中
	public void run()
	{
		while (true)
		{
			if (x > 0)
			{
				//添加sleep(),注意:sleep()会抛出异常
				try {
					Thread.sleep(10);  //让线程睡眠10ms
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("Runnable:"+x);
				--x;
			}
		}
	}
}
public class CRunableDemo1 {

	public static void main(String[] args) {
		RunDemo1 r = new RunDemo1();
		//3.通过Thread类建立线程对象,并将Runnable接口的子类对象作为参数
		Thread t1 = new Thread(r);
		Thread t2 = new Thread(r);
		Thread t3 = new Thread(r);
		Thread t4 = new Thread(r);
		//4.使用start开启线程
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

运行显示结果:

以上打印出了0,-1,-2等数字,发现没?(线程出问题了吧!!!)

出问题的原因是什么呢?

线程1进入,强制睡眠10ms;此时线程2进入,又强制睡眠10ms;线程3进入又强制睡眠10ms;线程4进入再强制睡眠10ms;

注意,以上4个线程睡眠时都已经进入了if语句,进入的时候x>0还是成立的;

好了,线程1醒来,开始打印打印5,4,3,2,这时候--x还没执行,线程2就醒来了,抢去了cpu的执行权.....................

二、线程同步

问题:对于上面的问题,我们是不是可以采取一个这样的措施?当线程1执行run代码段的时候,我们不让其他的线程来执行,直到线程1执行完,其他的线程才可以进入。

解决方案:好在Java里面本来就有这样的函数,将代码段包裹起来,就可以达到上面问题描述的效果。函数名:synchronized,需要一个参数,随便传个对象就ok了。

package thread.runable1.qdj;
//1.定义类实现Runnable接口
class RunDemo1 implements Runnable
{
	private int x = 5;
	Object obj = new Object();
	//2.覆盖Runnable接口中的run方法
	//将线程代码存放在run中
	public void run()
	{
		while (true)
		{
			synchronized (obj)
			{
				if (x > 0)
				{
					//添加sleep(),注意:sleep()会抛出异常
					try {
						Thread.sleep(10);  //让线程睡眠10ms
					} catch (Exception e) {
						e.printStackTrace();
					}
					System.out.println("Runnable:"+x);
					--x;
				}
			}
		}
	}
}
public class CRunableDemo1 {

	public static void main(String[] args) {
		RunDemo1 r = new RunDemo1();
		//3.通过Thread类建立线程对象,并将Runnable接口的子类对象作为参数
		Thread t1 = new Thread(r);
		Thread t2 = new Thread(r);
		Thread t3 = new Thread(r);
		Thread t4 = new Thread(r);
		//4.使用start开启线程
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

运行结果显示:

参考文献:Java视频 毕向东 主讲

原文地址:http://blog.csdn.net/qingdujun/article/details/39348093

时间: 09-17

Java Tread多线程(2)多线程安全问题的相关文章

Java Tread多线程(1)实现Runnable接口

作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/39347245 本文演示,Tread多线程实现Runnable接口,以及简单的说明为什么有这种创建线程的方法. 一.创建线程的2中方法: 1)继承Thread类实现多线程,参见我的上一篇文章:Java Tread多线程(0)一个简单的多线程实例 : 2)第二种方法就是实现Runnable接口,创建一个新线程. 二.为什么要有这两种方法创建线程呢? ①主要原因:就是方法1)不

Java笔记(23):多线程(01)

1.多进程及多线程的意义:多进程:单进程的计算机只能做一件事情,而我们现在的计算机都可以做多件事情.举例:一边玩游戏(游戏进程),一边听音乐(音乐进程).也就是说现在的计算机都是支持多进程的,可以在一个时间段内执行多个任务.并且呢,可以提高CPU的使用率.多线程:多线程的存在,不是提高程序的执行速度.其实是为了提高应用程序的使用率.程序的执行其实都是在抢CPU的资源,CPU的执行权.多个进程是在抢这个资源,而其中的某一个进程如果执行路径比较多,就会有更高的几率抢到CPU的执行权.我们是不敢保证哪

Java之旅--关于多线程

关于多线程的知识,有非常多的资料可以参考.这里稍微总结一下,以求加深记忆. 关于多线程在日常工作中的使用:对于大多数的日常应用系统,比如各种管理系统,可能根本不需要深入了解,仅仅知道Thread/Runnable就够了:如果是需要很多计算任务的系统,比如推荐系统中各种中间数据的计算,对多线程的使用就较为频繁,也需要进行一下稍微深入的研究. ThreadLocal与synchronized 区别ThreadLocal 与 synchronized ThreadLocal是一个线程隔离(或者说是线程

Java基础】并发 - 多线程

Java基础]并发 - 多线程 分类: Java2014-05-03 23:56 275人阅读 评论(0) 收藏 举报 Java 目录(?)[+] 介绍 Java多线程 多线程任务执行 大多数并发应用程序时围绕执行任务(task)进行管理的:所谓任务就是抽象的,离散的工作单元. 围绕执行任务来管理应用程序时,第一步是要指明一个清晰的任务边界.大多数应用服务器程序都选择了下面这个自然的任务辩解:单独的客户请求: 任务时逻辑上的单元: 任务 Runnable 表示一个任务单元(java.lang)

Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过start方法启动线程--->线程变为可运行可执行状态,然后通过数据产生共享,线程产生互斥---->线程状态变为阻塞状态---->阻塞状态想打开的话可以调用notify方法. 这里Java5中提供了封装好的类,可以直接调用然后构造阻塞状态,以保证数据的原子性. 2.如何实现? 主要是实现Blo

Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是CountDownLatch? 倒计时计数器,调用CountDownLatch对象的CountDown()方法就将计数器减一,当计数到达0时,则所有等待者或者全部等待者开始执行. 2.如何用? new CountDownLatch(1); 直接new,其构造函数必须传一个int类型的参数,参数的意思是: c

Java学习手记2——多线程

一.线程的概念 CPU执行程序,就好比一个人在干事情一样,同一个时间你只能做一件事情,但是这样的效率实在是太低了,在你用电脑的时候,听歌就不能浏览网页,看电影就不能下载视频,你想想是不是很蛋疼. 所以为了解决这个问题,CPU设计成了分时处理的方式,即不同的时间CPU做不同的事情,这样就大大提高了效率,能这样做的原因是因为CPU相对于人的接收信息的速度,快得多!也就是说,你边听歌边浏览网页,看上去好像音乐播放器和浏览器两个程序在同时工作,其实他们是分时在工作,即播放器工作一会,浏览器工作一会,这样

Java 并发和多线程(一) Java并发性和多线程介绍[转]

作者:Jakob Jenkov 译者:Simon-SZ  校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行. 随着多任务对软件开发者带来的

Java简明教程 12.多线程(multithreading)

单线程和多线程 关于它们的区别,zhihu上有一个回答,我认为十分不错,如下: 1. 单进程单线程:一个人在一个桌子上吃菜. 2. 单进程多线程:多个人在同一个桌子上一起吃菜. 3. 多进程单线程:多个人每个人在自己的桌子上吃菜. 多线程的问题是多个人同时吃一道菜的时候容易发生争抢.例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了.此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢. 例子: 多线程: 浏览器浏览一个页面,里面有很多图片,多

java swing实现的多线程实例代码教程-赛马demo

代码下载:http://www.zuidaima.com/share/1825492473826304.htm 原文:java swing实现的多线程实例代码教程-赛马demo 项目截图: 运行截图: java swing实现的多线程实例代码教程-赛马demo,布布扣,bubuko.com