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

原创 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.同步块

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

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

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

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

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



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



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

相关文章推荐

多线程同步访问共享内存

下面讨论的是特定于网络编程中多线程对共享内存的同步访问,原理可以用于其它应用. 首先看看创建线程函数: #include int pthread_create(pthread_t ...

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

Java 多线程同步问题的探究(五、你有我有全都有—— ThreadLocal如何解决并发安全性?)【更新重要补疑】Java 多线程同步问题的探究(四、协作,互斥下的协作——Java多线程协作(wa...

秒杀多线程第四篇 一个经典的多线程同步问题

上一篇《秒杀多线程第三篇原子操作 Interlocked系列函数》中介绍了原子操作在多进程中的作用,现在来个复杂点的。这个问题涉及到线程的同步和互斥,是一道非常有代表性的多线程同步问题,如果能将这个问...

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

上篇通过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的,为什么会产生这样的结果呢,因为建立的Count对象是线程共享的,一个线程改变了其成员变量num值,下一个...
  • ghsau
  • ghsau
  • 2012年04月04日 10:49
  • 105272

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

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

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

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

线程中的冲突问题

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

Spring 是如何解决并发访问的线程安全性问题的

springmvc的controller是singleton的(非线程安全的),这也许就是他和struts2的区别吧!和Struts一样,Spring的Controller默认是Singleton的,...

Java-LCS最长公共子序列(动态规划实现)

一个序列S任意删除若干个字符得到新序列T,则T称为S的子序列。若两个序列X和Y的公共子序列中,长度最长的那个字序列称为X和Y的最长公共子序列(LCS)。 Xi表示字符串的前i个字符,Yj表示字符串的前...

提取最长回文子串的java实现

题目描述 给定一个字符串,找出该字符串的最长回文子串。回文字符串指的就是从左右两边看都一样的字符串,如aba,cddc都是回文字符串。字符串abbacdc存在的回文子串有abba和cdc,因此它的最...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:解决线程同步带来的访问冲突问题
举报原因:
原因补充:

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