`
御天田
  • 浏览: 15260 次
  • 性别: Icon_minigender_2
文章分类
社区版块
存档分类

线程同步小结

阅读更多
Java中的线程同步小结

最近听了大家讲一些线程同步的知识,个人感觉只学到了一些皮毛,以前也写过有关线程的小程序,但没想这么多,像神马线程同步问题的。。。在这里就跟大家来分享一下我这两天学到的一点东西吧。个人很菜。还望各位大神路过飘过的多多指教昂。。。

什么是线程同步?
“线程同步”刚接触到这个名词时,顾名思义,就是多个线程一起跑的意思咯。其实不然昂。恰恰相反。线程同步就是各个线程为了竞争同一互斥资源而产生的。当一个资源必须互斥使用时,那么此时的线程就不能一窝蜂的全上,必须排队等待使用这段资源。于是就产生了线程同步。实际上就是各个线程排队等待一段临界资源的问题(需注意的是:这段资源必须是共享的,若不是共享的就没有同步的必要了)。
为什么要进行线程同步?
线程给我们带来了很多好处,但是由于线程可以执行程序中的任意代码段,而且线程的运行是有java虚拟机控制的。所以就不避免出现多个线程对同一资源的操作,产生错误。比如:现有一银行账户里有1000元,一人拿存折去柜台取,另一人到自动取款机取。则这两个人就相当于两个线程,账户则是临界资源。若它们之间不同步进行,那银行就亏大发了。。。
Java中如何实现多线程同步的?
多线程的线程同步机制实际上是靠锁来实现的,在java中常用到关键字synchronized(同步的),使用synchronized块或者synchronized方法是标志一个监视区域,当每次进入一个监视区域时,java虚拟机都会自动锁上对象或者类,我们不需要自己动手加锁,对象锁是java虚拟机内部使用的。当线程运行到有synchronized修饰的程序段时,会先检查是否有线程在运行它,否则就排队等待,只有当没有线程使用它的时候才能运行该段程序,一旦进入后就独占这段资源直到其释放结束。

Synchronized关键字:
不同实例中的synchronized方法是互不干扰的。其他线程照样可以访问相同类的其他实例对象中的synchronized方法
Synchronized可以定义一个锁定方法或者一个程序块。具体表现为:
Synchronized(同步锁){
//需要同步执行的代码
}
注意--->synchronized(object){}object要是同一个锁对象

举个例子可能会表达的清楚一点
public static final Object ob=new Object();//生成一个同步锁对象

F1(){
Synchronized(ob){
	//代码A
	//访问共享资源,需要同步
}}
F2(){
Synchronized(ob){
	//代码B
	//访问同一个共享资源,需要同步
}}
假设现在有10个线程竞争代码A,10个线程竞争代码B,而他们都得竞争同一个锁(ob),同一时刻,只有一个线程能获得锁ob的使用权,而其他的线程就只能排队等待了,进入线程的就绪队列。
生产/消费者模型:
仅仅使用上面所说的同步锁往往不能满足实际需求,当我们的一个线程在运行的时候需要等待使用另外一个线程的结果才能继续执行,那么就要用到生产/消费者模型了。简单的来说,A负责向容器C中放入元素,条件是容器C为空的时候。而B需要从容器中取走一个元素,条件自然就是C不为空。就相当于一个“等待/通知”模型了。比如:
// 锁定同一个对象
			synchronized (this.dataList) {
	//获得锁控制权后执行代码
				while (dataList.size() > 0) {//若队列中存在元素,则进入等					待队列
					try {
						dataList.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} while(dataList.size() == 0) {
					this.count++;
					data dt = new data();//data是要放入的数据对象
					dt.id = count;
					dt.name = "气球";
					dataList.add(dt);
					System.out.println("队列中加入了" + dt.toString());
					try {
						Thread.sleep(1000);
					} catch (Exception ex) {
						ex.printStackTrace();
					}
					// 加入新元素后通知消费者
					dataList.notify();
				}
			}


这里需要注意wait()和notify()/notifyAll():
wait()和notify()/notifyAll()都是Object类下的方法,也就是说所有的类都有这三个方法,因为这一方法在阻塞时要释放其占用的锁,而锁是任意对象都有的,当对象调用wait()时就进入等待队列,并释放该对象占有的锁。

Wait():它与线程的sleep方法不同,sleep是线程类的一个方法,使线程进入阻塞状态,没有得到CPU时间,但没有释放该线程占用的资源,它依然保存着锁,别的线程就进不来。而wait就相当于该线程放弃了自己已占用的资源,使自己进入等待状态,直到收到通知notify后再重新竞争资源。运行时要捕捉一个异常IllegalMonitorStateException。

Notify()/notifyAll():负责唤醒某个处于等待队列的线程,要说具体唤醒哪个线程则是不确定的,是又JVM负责,注意这里并不与线程本身的优先级有关。notifyAll()与notify()的唯一区别就是notifyAll()解除了所有因调用了本身wait方法而处于等待状态的线程,最终都是只有那个获得锁的使用权的线程才能开始执行。
分享到:
评论
2 楼 ronaldoLY 2013-01-19  
1 楼 xiaoyjj 2013-01-17  
~~~~~~

相关推荐

    java线程详解

    八、线程同步小结 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:volatile关键字 Java线程:新特征-线程池 一、固定大小的线程池 二、单任务线程池 三、可变尺寸的线程池 四、延迟连接池 五、...

    线程同步的入门级说明线程同步的入门级说明线程同步的入门级说明

    #### 五、小结 线程同步是多线程编程中不可或缺的一部分,它可以帮助开发人员解决因多线程环境导致的数据不一致问题。在.NET中,通过使用Mutex类、Monitor类(配合lock关键字)以及ReaderWriterLock类等工具,可以...

    Java多线程小结

    ### Java多线程小结 #### 一、多线程的概念与意义 多线程是Java编程中的一个重要概念,指的是程序在运行时可以同时执行多个线程的能力。它能够提高程序的性能,尤其是在多核处理器的环境下。多线程使得程序能够更...

    Java线程类小结(附思维导图)

    我们将探讨`Thread`类、`Runnable`接口、线程的状态、线程同步以及线程池等相关知识点。 1. **线程基础** - **Thread类**:Java中的`Thread`类是所有线程的基类,包含了启动、控制和停止线程的方法,如`start()`、...

    用多线程同步方法解决生产者-消费者问题

    5. **设计小结与心得** - 总结设计过程中的挑战和解决方案,比如如何有效地实现线程同步,如何避免死锁,以及如何优化性能。 - 分享从项目中学到的知识和经验,可能包括多线程编程的技巧、并发控制的理解以及调试...

    多线程小结

    为了确保多线程环境下的数据一致性,C#提供了多种线程同步机制,包括但不限于`lock`语句、`Monitor`类、`AutoResetEvent`、`ManualResetEvent`等。 ##### Lock `lock`关键字可以实现简单的互斥锁机制,用于保护...

    多线程编程指南(系统描述了线程标准 线程同步 多线程编程原则 等)

    线程同步20 使用64 位体系结构20 2 基本线程编程23 线程库................................................................................................................................................. ...

    Visual Basic.NET线程参考手册

    3.5 端到端的示例 3.5.1 编写自己的线程安全包装器 3.5.2 数据库连接池 3.6 本章小结第4章 设计模式 4.1 应用程序中的多线程 4.2 STA线程模式 4.3 MTA线程模式 4.3.1 指定线程模式 4.3.2 设计线程应用程序 4.3.3 ...

    C++多线程编程入门小结.pdf

    根据给定文件信息,以下是对"C++多线程编程入门小结.pdf"文件内容的知识点说明: ### 知识点一:C++多线程编程基础 C++多线程编程是指在C++程序中同时执行多个线程,以利用现代处理器的多核能力,提高程序的执行...

    C++多线程编程入门小结

    - **资源共享与同步**:在多线程环境中,多个线程可能共享同一块内存区域。为了避免数据竞争和不一致性问题,需要使用互斥锁(Mutex)、信号量(Semaphore)、临界区(Critical Section)等机制进行同步。 - **死锁...

    Linux编程技术-实验4 多线程编程.doc

    Linux多线程编程技术 本实验报告的主要内容是关于...五、疑难小结: 本实验中遇到的困难是对共享变量的使用和理解不够深入,对消费者和生产者代码的编写还不是太熟练。需要更多地查询资料和实践来提高自己的技术。

    操作系统实验报告_进程同步与互斥.doc

    实验中,设计了一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。 实验环境:Windows 2000/XP + Visual C++ 6.0 实验容:以生产者-消费者模型为依据,在 Windows 2000/XP...

    java应用程序中使用线程

    锁定排序 3.6 线程优先级 3.7 监控程序线程 3.8 在应用程序中加入线程 ...线程中的过时方法 3.12 DownloadFiles类 3.13 未捕捉的异常 3.14 自愿放弃处理器 3.15 并发工具 3.16 小结

    操作系统-创建多线程-读者写者

    #### 小结 本文通过对一个简单的多线程程序的分析,介绍了如何在Windows环境中使用`CreateThread`函数创建线程,并简要探讨了生产者-消费者模式和读者写者问题。在实际开发中,还需要深入研究多线程同步机制,以确保...

    关于java实现群聊和同步画图小结。

    在Java编程领域,实现群聊和同步画图是两个具有挑战性的任务,它们涉及到网络通信、多线程、图形用户界面(GUI)以及数据同步等多个关键知识点。这篇博客的作者通过分享自己的实践经验和代码示例,为我们揭示了如何...

    Android 线程 多线程 Multi-thread

    #### 七、小结 本文介绍了Android中线程的相关概念、使用方法及其同步机制。合理运用线程不仅可以提高程序的性能,还能增强用户体验。在实际开发中,应根据具体需求选择合适的线程模型和技术方案。

    VC++多线程编程

    #### 六、小结 通过本文的学习,我们了解了VC++环境下多线程编程的基础知识和技术要点。多线程编程虽然能显著提高程序性能,但也存在诸多挑战,如资源竞争和线程安全等问题。因此,在实际开发中需要结合具体场景...

Global site tag (gtag.js) - Google Analytics