解决线程同步带来的访问冲突问题

原创 2016年05月30日 16:41:57

线程的同步也可以称为并发,由于进程是处理机分配资源的最小单位,

就会出现多个线程共同享用一个资源的想象,在带来方便的同时也带来了访问资源冲突这个严重的问题,

JAVA语言在提供了专门机制解决这种冲突,有效的避免了同一个数据对象被多个线程同时访问



关键字synchronized,在多线程情况下,可以确保资源安全,即线程安全

以前提到的HashTable线程安全,HashMap线程不安全,说的也就是线程同步问题

HashTable的put方法用synchronized关键字修饰,所以它的线程安全



同步又分为了同步块以及同步方法

同步方法:方法前面添加synchronized关键字

同步块:synchronized(引用类型|this|类.class){ }




利用关键字synchronize来解决之前遗留的线程不安全的问题

在博文-[线程的阻塞+通过外部干涉终止一个线程]中,当加入线程休眠模拟网络延迟时,出现了多线程并发错误


1.同步方法

解决方法其实很简单,见代码

public class SynDemo01 {
	public static void main(String[] args) {
		web1 web = new web1();

		Thread t1 = new Thread(web);
		Thread t2 = new Thread(web);

		t1.start();
		t2.start();
	}
}

class web1 implements Runnable{

	public int num=10;
	private boolean flag=true;
	
	@Override
	public void run() {
		while(flag){
			test2();
		}
	}
	
	/**
	 * 线程不安全
	 */
	public void test1(){
		if(num<=0){
			flag=false;
			return;
		}
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println(Thread.currentThread().getName()+"抢到了 "+num--);
	}
	
	
	/**
	 * 线程安全
	 */
	public synchronized void test2(){
		if(num<=0){
			flag=false;
			return ;
		}
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println(Thread.currentThread().getName()+"抢到了 "+num--);
	}	
}

为方法添加关键字就可以使资源上锁,也就是当t1,t2这两个线程都需要进入到test2方法时,当其中一个进入以后,

就会阻止另一个线程也进入,这样就不会出现线程不安全的问题了

当你的方法添加了synchronize关键字以后,只能被一个线程访问



2.同步块

在方法签名中添加关键字,是将整个方法体都锁定了,所有方法体都只允许一个线程访问

而同步块可以只将需要锁定的部分代码锁定起来

使用同步块就带来了锁定资源和锁定范围的问题

锁定范围不能过大,造成资源利用率低下,也不能过小,没有锁定正确线程还是不安全的

这也是解决多线程并发的难点所在



通过代码实例操作,可以看出来线程安全要比线程不安全慢,线程安全有等待,效率低



版权声明:本文为博主原创文章,未经博主允许不得转载。

线程中的冲突问题

我们知道,对于一个Thread的对象t,当调用start方法后,该线程就会一直执行。 那么什么是线程中的冲突问题呢?如果现在有两个线程t1、t2,并且这两个线程中的run方法同时操作同一数据,就比如...
  • huai814586181
  • huai814586181
  • 2015年03月26日 20:31
  • 784

关于Java的线程问题总结

不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚的Java开发职位都要求开发者精通多线程...
  • g552092947
  • g552092947
  • 2016年08月12日 22:25
  • 978

多线程程序处理内存泄漏和访问冲突问题

多线程程序开发与单线程开发相比,需要考虑的问题更多,难度更大,稍不留神就容易出现内存泄漏,要不就是访问冲突。 内存泄漏,还可以使用内存泄漏检测工具进行检测,使用visual leak director...
  • baiguanglinyun163
  • baiguanglinyun163
  • 2015年09月14日 15:58
  • 544

JAVA高并发多线程必须懂的50个问题

http://www.importnew.com/12773.html ImportNew 首页所有文章资讯Web架构基础技术书籍教程Java小组工具资源 Java线程面试题 Top 50 2...
  • u011163372
  • u011163372
  • 2017年06月30日 14:28
  • 4183

java 多线程 解决资源冲突

/** * 在其他对象上同步 * * DualSync.f()(通过同步整个方法)在this同步,而g()有一个在syncObject上同步 * 的synchronized块。因此,这两个同...
  • liang_henry
  • liang_henry
  • 2016年12月06日 17:46
  • 884

Queue<T> 需要注意的多线程冲突问题

最近在做一个AsyncEvent,内部使用了Queue,因为效率问题,所以不敢用lock,以为Queue也就push一个T,不用同步。 结果今天就崩了,Queue.Enqueue 出错,提示很奇怪:...
  • norsd
  • norsd
  • 2012年05月23日 10:47
  • 3562

读取/写入位置发生访问冲突

问题描述 C/C++程序运行时提示读取/写入位置发生访问冲突。例如:0x00007FFF33515D43 (swscale-4.dll) (QTDemo0.exe 中)处的第一机会异常:  0xC0...
  • gkzscs
  • gkzscs
  • 2016年06月08日 15:41
  • 3929

关于VS访问冲突的原因及解决方法

唉,搞了一天,总是内存访问错误,这个急啊。。。好在最后一瞬间觉悟了。。。现在总结一下吧。。。 截图如下: 出现这种错误的原因大概有以下几种: 1、数据越界...
  • u011747846
  • u011747846
  • 2014年06月03日 22:05
  • 1705

Java线程(二):线程同步synchronized和volatile

上篇通过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的(其实是巧合,多运行几次,会产生不同的输出结果),为什么会产生这样的结果呢,因为建立的Count对象是线程...
  • ghsau
  • ghsau
  • 2012年04月04日 10:49
  • 112449

Java 多线程同步问题的探究-经典讲解

Java 多线程同步问题的探究(五、你有我有全都有—— ThreadLocal如何解决并发安全性?)【更新重要补疑】Java 多线程同步问题的探究(四、协作,互斥下的协作——Java多线程协作(wa...
  • liuhl0910
  • liuhl0910
  • 2015年05月20日 15:39
  • 1015
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:解决线程同步带来的访问冲突问题
举报原因:
原因补充:

(最多只允许输入30个字)