窗外狂风大作,实在不想在睡觉时刻本着不完成誓不罢休不睡觉的精神在这邹文章。
的确,哪怕再小的知识点要吃透,不花点功夫可是没可能的。所以就线程机制给我个把星期估计也讲不明白,到头来只是重复老师的话或者网上技术牛人的博客。此刻呢,也只能绕过代码层面,说说理解和
体会吧。
首先,我习惯把知识整理成小体系,逻辑清晰,而每一块的具体当然有大把时间上网搜,进而学习。
不闲扯~
- 概念,与进程联系与区别。
- 用方法。Thread和Runnable
- 线程游戏,熟悉线程方法使用,出错。
- 进一步了解线程原理,工作机制,提出同步,异步概念。
接下来就同步详细介绍。异步相关概念将在后续学习中逐步介绍。
首先,线程同步到底是什么概念?
同步是表示线程之间存在的一种状态,还是存在的一种问题,还是解决线程共享资源被争夺的一种解决方法?
因为“同步”二字本身容易混淆,“同”非共同,一起,而是“协作”,“配合”的意思,即“排队”,一个一个对共享资源进行操作。有这么一句话:线程同步就是线程排队,同步就是避免线程“同步“执行。
综述,线程同步首先是一种解决问题的方法,即线程同步机制(动作)。也是问题被解决之后的一种状态描述,即线程之间同步了(状态)。当然,把它理解成问题的思路肯定是把“同“ 想成 ”共同“的意思。
这样,理解线程同步相关概念,例如,同步锁(synchronized关键字),wait()与notify()方法,以及生产消费者模型,双缓冲,线程池等之间的联系。
其次,何时需要线程同步以及为什么需要?
A.对共享资源的使用,引起争夺与混乱。
B.共享资源是变量,即任何线程可以改其属性
举个简单的例子,线程A和线程B分别对变量x(=0)进行加1和减1的操作。而线程的执行顺序是未知的,且该操作不是原子性的,即在计算机底层连简单的+1操作也是分为3个步骤的(从内存取出,+1,放回内存),操作系统本着充分利用资源和时间响应的精神,自然会在各种调度程序的控制下,在A线程未完成加1操作之前,B线程进行减1的操作。而最终x的值无法预知。
我们当然不能让这种事情让程序出错啊~那就让线程同步吧~即让线程协同配合着使用共享资源。
有这么几种方法: 1.同步锁 2.等待/通知模式
1.同步锁的基本思路是指:
对共享资源加锁,且只有一把钥匙。同一时刻只存在一个持有钥匙的线程在使用它。
(情景:给银行账户存取款。银行初始有100元,现在启动6个线程,随即进行存取操作,显而易见,必须要线程同步.)
A.synchronized关键字——给方法或者代码段加锁
a)锁定方法
Bank bank=new Bank(); myThread thread1=new myThread(bank,20); myThread thread2=new myThread(bank,-120); myThread thread3=new myThread(bank,50); myThread thread4=new myThread(bank,90); myThread thread5=new myThread(bank,-40); myThread thread6=new myThread(bank,200); thread1.start(); .......
public class myThread extends Thread { private int money; private Bank bank; myThread(Bank bank, int money) { this.bank = bank; this.money = money; } public void run() { bank.process(money); } }
public class Bank { private int total = 0; public Bank(int total) { this.total = total; } public void process(int money) { try { Thread.sleep(100); this.total += money; System.out.println("对银行已操作:" + money + "银行现存:" + this.total); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行上述代码,可发现完全是混乱的,而在process()方法前加synchronized关键字即可锁定该方法,即每次只让一个线程改变账户存款。
b)锁定方法块,即不是对整个方法进行锁定,只对那些操作共享资源的关键代码段进行加锁。
synchronized (this){
this.total+=money;
System.out.println("对银行已操作:"+money+"银行
现存:"+bank.getTotal());
}
注意:synchronized ()括号里需要一个对象,此例中,可以直接填this,或者new一个Object对象或者一个大小为0的数组,即:
Object obj=new Object();
synchronized (obj){};
B. 用Lock加锁。
首先实例化一个Lock对象,在process()方法中传进去,或者利用单例模式保证每个线程拥
有的是同一把锁即可。如:
void process(int money,Lock lock) { try { lock.lock(); Thread.sleep(100); this.total += money; System.out.println("对银行已操作:" + money + "银行现存:" + this.total); Thread.sleep(100); lock.unlock(); } catch (InterruptedException e) { e.printStackTrace(); } }
2.等待/通知机制——wait()/notify()方法
关于wait/notify,还有生产消费者模型与线程同步的关系,区别与应用将在后续继续呈上自己的心得哦~~
相关推荐
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。 举例1: 银行存款 5000。柜台,折:取3000;提款机,卡:取 3000。剩余:2000 举例2...
C#线程同步的几种方法 C#线程同步的几种方法
.NET多线程同步方法详解(一):自由锁(InterLocked) 本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再赘述了。直接接入主题,在多线程开发的应用中,线程同步是不可避免的。在.Net框架中,...
1.使用三种VC的多线程同步方法编写一个多线程的程序(要求在屏幕上先显示Hello,再显示World)。 1)基于全局变量的多线程同步程序; 2)基于事件的多线程同步程序; 3)基于临界区的多线程同步程序。
MFC 多线程及线程同步 MFC 多线程及线程同步 MFC 多线程及线程同步
java线程同步java线程同步java线程同步
简单学习用例,利用线程锁对线程同步进行控制,保证对公共资源的访问不出现错误!
本文件为操作系统中的线程同步实验的实验报告,有详细的代码和解释。
线程同步的四种方法的代码。事件 互斥量 信号量 临界区
多线程中的同步问题的几种解决方案,新手可以看看。主要通过临界区线程同步,互斥内核对象、事件内核对象,信号量内核对象来实现线程同步问题。
介绍了linux线程同步的所有方式,包括互斥、自旋、信号量、条件变量等技术
操作系统实验 多线程同步与互斥 java编写 可动态创建
通过模拟公交车运行时,司机,售票员以及乘客之间的同步状态来实现线程同步
很不错的Delphi多线程和线程同步的例子,完整源码 原来的一个不知道CSDN怎么把文件搞丢了!新传一个资源,包含一个线程排序的例子!代码均搜集自网上!
C#_线程同步lock,Monitor,Mutex,同步 互斥 监控 锁
简单实现多线程同步示例(模拟购票系统),内容为实现多线程同步过程,模拟购票系统进行同步购买情况;该处并未考虑线程守护问题,后期将对线程锁等安全问题进行初步研究!
C#线程同步,多个线程去执行,检测到最后一个线程执行完成,主线程继续执行其他业务AutoResetEvent
本工程中包含了线程同步的五种方法,现在拿出来和大家一起分享,VC6.0编译测试通过,工程中包含了5个小工程,具体讲述每种线程同步方法的具体使用列子,而且有详细的注释。
线程同步技术剖析!! 自己看了还不错!需要的下吧
多线程同步解决卖票问题