必威体育Betway必威体育官网
当前位置:首页 > IT技术

实现线程同步的几种方法

时间:2019-10-14 07:13:26来源:IT技术作者:seo实验室小编阅读:54次「手机版」
 

线程同步

  • 在多线程程序中,会出现多个线程抢占一个资源的情况,这时间有可能会造成冲突,也就是一个线程可能还没来得及将更改的 资源保存,另一个线程的更改就开始了。可能造成数据不一致。因此引入多线程同步,也就是说多个线程只能一个对共享的资源进行更改,其他线程不能对数据进行修改。
  • 1.如下一个两个线程对一个银行账户进行存钱的小实例,其中使用synchornized修饰方法实现线程的同步
  • 代码如下:
class bank{
	private int count=100;
	public synchronized void dispit() {
		  count+=10;
	}
	public int getcount() {
		return count;
	}
}
class ThreadCount extends Thread{
	private bank count;
	private JTextArea textarea = new JTextArea();
	public ThreadCount(bank count,JTextArea textarea) {
		this.count = count;
		this.textarea = textarea;
	}
	public void run() {
		for(int i=0; i<10; i++) {
			count.dispit();
			textarea.APPend("账户余额为:"+count.getcount()+"\n");
		}
	}
}

2.同步是一种高开销的操作,因此应该尽量减少同步内容,因此也可以使用修饰代码块来代替修饰整个方法。

class bank{
	private int count=100;
	public void dispit() {
		synchronized(this) {
		  count+=10;
		}
	}
	public int getcount() {
		return count;
	}
}
class ThreadCount extends Thread{
	private bank count;
	private JTextArea textarea = new JTextArea();
	public ThreadCount(bank count,JTextArea textarea) {
		this.count = count;
		this.textarea = textarea;
	}
	public void run() {
		for(int i=0; i<10; i++) {
			count.dispit();
			textarea.append("账户余额为:"+count.getcount()+"\n");
		}
	}
}

3.使用volatile修饰数据,对于当下问题,只用使用volatile来修饰账户的余额变量即可。该修饰词是对域变量的访问提供了以这种防锁机制,相当于告诉虚拟机,该域的变量可能被更改。因此每次使用该域都要重新计算,而不是从寄存器中取出数据。从而实现线程的同步。该修饰词不能修改final类型变量

class bank{
	private volatile int count=100;
	public void dispit() {
		  count+=10;
	}
	public int getcount() {
		return count;
	}
}
class ThreadCount extends Thread{
	private bank count;
	private JTextArea textarea = new JTextArea();
	public ThreadCount(bank count,JTextArea textarea) {
		this.count = count;
		this.textarea = textarea;
	}
	public void run() {
		for(int i=0; i<10; i++) {
			count.dispit();
			textarea.append("账户余额为:"+count.getcount()+"\n");
		}
	}
}

4.使用重入锁实现线程同步。使用类ReentrantLock类来定义锁,其中lock()方法为打开锁,unlock()方法为关闭锁

类似于synchronized修饰方法有一样功能。使用锁时间需要注意应该及时放开锁,不然会进入死锁状态。一般是在finally中释放锁

class bank{
	private volatile int count=100;
	private Lock lock = new ReentrantLock();
	public void dispit() {
		 lock.lock();
		 try {
		  count+=10;
		 }finally{
			 lock.unlock();
		 }
	}
	public int getcount() {
		return count;
	}
}
class ThreadCount extends Thread{
	private bank count;
	private JTextArea textarea = new JTextArea();
	public ThreadCount(bank count,JTextArea textarea) {
		this.count = count;
		this.textarea = textarea;
	}
	public void run() {
		for(int i=0; i<10; i++) {
			count.dispit();
			textarea.append("账户余额为:"+count.getcount()+"\n");
		}
	}
}

代码的输出结果如下:

在这里插入图片描述

可以看到,每次增加10 的时间只有一个线程在进行,也就是线程的同步

5.使用Threadlocal类来管理。不过该方法和同步机制不相同。该类管理的变量在每个线程中都有自己的副本,副本之间相互独立,因此获得的结果和其他不同。

class bank{
	private static ThreadLocal<integer> count = new ThreadLocal() {
	   protected Integer initialValue() {
		   return 100;
	   }
	};
	private Lock lock = new ReentrantLock();
	public void dispit() {
		 lock.lock();
		 try {
		  count.set(count.get()+10);
		 }finally{
			 lock.unlock();
		 }
	}
	public int getcount() {
		return count.get();
	}
}

class ThreadCount extends Thread{
	private bank count;
	private JTextArea textarea = new JTextArea();
	public ThreadCount(bank count,JTextArea textarea) {
		this.count = count;
		this.textarea = textarea;
	}
	public void run() {
		for(int i=0; i<10; i++) {
			count.dispit();
			textarea.append("账户余额为:"+count.getcount()+"\n");
		}
	}
}

结果如图:

在这里插入图片描述

可以看到,在改程序中,好比两个账户相互独立,互不干扰一样。同样解决了相同的变量访问冲突问题。

相关阅读

linux利用setpriority调整线程优先级,测试优先级对线程

以下测试是为了验证setpriority函数对线程是否有效,理论上linux kernel是不区分调度是不区分线程和进程的。用户线程和进程的区别

程序,进程,线程的区别和联系

进程和程序区别和联系表现在以下方面:1)程序只是一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体。而进程则不同

qt线程(转)----这篇很专业!

本文档是自己所整理的一份文档,部分是原创,还转贴了网上的一此资料(已经标明了),(难点是多线程的编写),是有源代码的,大家可以作为参

java中Executor框架之ThreadPoolExcutor和ScheduledTh

转载自: https://blog.csdn.net/javazejian/article/details/50890554 java多线程-概念&创建启动&中断&守护线程&

线程属性pthread_attr_t简介

线程属性pthread_attr_t简介 参考资料: 1,https://blog.csdn.net/sinat_36184075/article/details/71598639 2,https://blog.csdn.n

分享到:

栏目导航

推荐阅读

热门阅读