一、线程同步
线程同步通常是指做同类事情的各个线程,对一个同共享变量不能同时访问。
进程同步的几种方式:
1、同步代码块
synchronized(Object){
需要被同步的代码块
}
如果将 run方法中的代码全部放到同步块里,那么就成了单线程,失去了意义。
同步代码块的优缺点:
好处:解决多线程的安全问题。
弊端:每个线程只要获得CPU执行权,每次都要判断锁,较为消耗资源。越安全越麻烦!有利必有弊!
2、同步函数
同步函数没有显式指定同步锁,那么它是怎样实现同步的呢?函数需要被对象调用,那么函数都有一个所属对象的引用——this,所以同步函数
使用的锁就是this。
现在知道了普通函数的同步锁是this,那么静态方法不是由对象调用,没有this,那么它使用的同步锁又是什么呢?它的锁是类所对应的Class字节
码文件对象。
经试难,两个线程分别执行上面以Ticket.class为锁的同步代码块和静态方法,这两个线程成功地实现了进程同步!这说明静态方法确实是以字节码文件
对象为同步锁的。
线程同步需要明确的问题:
1、首先明确哪些代码是多线程运行代码
2、明确哪些数据是共享数据
3、明确多线程运行代码中哪些语句是操作共享数据的
线程同步
二、线程通信
线程通信通常是指做不同类事情的各个线程,除了不能同时访问共享变量,还要在一定条件下相互通信。比如
生产者消费者。在产品池为空时,消费者阻塞,此时如果生产者生产一个产品,则通知消费者可以进行消费;
当产品池满时,生产者阻塞,此时如果消费者消费掉一个产品,则通知生产者可以进行生产。对产品个数的
操作除了不能同时进行外,还要关注产品个数为0和为n 的情况。这就是线程通信与线程同步不同之处。
1、多个生产者多个消费者,使用notity 导致全部等待问题
使用notify唤醒不该唤的线程,该唤醒的线程却没有唤醒,导致死锁。比如两个生产者A,B和两个消费者M,和N。当产品数为0时,假设某一时刻,消费者M消费了一个产品,此时A,B和N同时都在等待,并且N在CPU队列中最前面,当调用notify后N线程被唤醒,但此时产品数为0,此时消费者N就会处于等待。理应将对方唤醒,但唤醒的本方,就这样导致了四个线程全部等待。
这时,如果使用notifyAll就可以解决。将所有线程都唤醒,此时就不会出现全部都等待的状况。
2、停止线程
只有一种方式,即run方法结束。只要控制住循环,就可以让方法结束,也就是线程结束。iterrupte 将处于冻结状态的线程,强制地恢复到运行状态中来。也就是清除线程的
冻结状态。
三、Lock 锁
Lock类是jdk1.5中新加入的同步锁的升级解决方案。Lock
实现提供了比使用 synchronized
方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的Condition
对象。
锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不过,某些锁可能允许对共享资源并发访问,如ReadWriteLock
的读取锁。
synchronized
方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问,但却强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。
虽然 synchronized
方法和语句的范围机制使得使用监视器锁编程方便了很多,而且还帮助避免了很多涉及到锁的常见编程错误,但有时也需要以更为灵活的方式使用锁。例如,某些遍历并发访问的数据结果的算法要求使用 "hand-over-hand" 或 "chain locking":获取节点 A 的锁,然后再获取节点 B 的锁,然后释放 A 并获取 C,然后释放 B 并获取 D,依此类推。Lock
接口的实现允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁,从而支持使用这种技术。
随着灵活性的增加,也带来了更多的责任。不使用块结构锁就失去了使用 synchronized
方法和语句时会出现的锁自动释放功能。在大多数情况下,应该使用以下语句:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
分享到:
相关推荐
线程同步Synchronized,监视器monitor和锁lock的关系2---马克-to-win java视频
NoHttp核心架构之多线程通信、线程安全、线程同步;synchronized锁,Lock锁;具体讲解请移步博客:http://blog.csdn.net/yanzhenjie1003/article/details/50992468
NoHttp核心架构之多线程通信、线程安全、线程同步;synchronized锁,Lock锁;具体讲解请移步:http://blog.csdn.net/yanzhenjie1003/article/details/50992468
线程同步Synchronized,监视器monitor和锁lock的关系2---马克-to-win java视频
1. Java多线程学习(一)Java多...6. Java多线程学习(五)线程间通信知识点补充 7. Java多线程学习(六)Lock锁的使用 8. Java多线程学习(七)并发编程中一些问题 9. Java多线程学习(八)线程池与Executor 框架
线程安全问题的产生是因为多个线程并发访问共享数据造成的,如果能将多个线程对共享数据的并发访问改为串行访问,即一个共享数据同一...内部锁是通过synchronized关键字实现的,显式锁则是通过Lock接口的实现类实现的。
线程同步Synchronized,监视器monitor和锁lock的关系1---马克-to-win java视频
JDK5.0后Java提供了一种更加强大的线程同步机制。一种显式定义同步锁对象来实现锁,提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock锁。 # synchronized锁与...
.NET多线程同步方法详解(一):自由锁(InterLocked) 本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再赘述了。直接接入主题,在多线程开发的应用中,线程同步是不可避免的。在.Net框架中,...
Lock接口与synchronized关键字在Java并发编程中都是用于实现同步机制的重要工具,但它们在使用方式、功能特性以及灵活性等方面存在一些显著的差异。 首先,从使用方式上来看,synchronized是Java语言内置的关键字,...
(注意,本资源附带书中源代码可供参考) 多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字与实例来介绍Java线程相关的设计模式概念,并且通过实际的Java程序范例和 UML图示来一一解说,书中...
2.3 线程本地存储(Java.lang.ThreadLocal) 15 2.4 线程阻塞 17 2.4.1 调用sleep(millisecond)使任务进入休眠状态 17 2.4.2 等待输出与输入 17 2.4.3 对象锁不可用 17 2.4.4 通过wait()使线程挂起。 17 2.5 线程...
各线程之间变量不可见,线程通信通过共享主内存实现。 volatile 仅保证可见性 作用 不会被缓存在寄存器或其他对cpu不可见的地方 强制其他线程读主内存 编译器和运行时不会讲该变量的操作与其他内存操作一起重...
由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问...每个对象只有一个锁(lock)与之相关联。 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
多线程同步和通讯完整示例,包括synchronized、wait-nofity机制、lock锁
4.讲解了synchronized关键字 , 它使用起来比较麻烦, 所以在Java5中提供了Lock 对象 , 以求能更好地实现并发访问时的同步处理, 包括读写锁等相关技术点。5.讲解了Timer定时器类, 其内部实现就是使用的多线程技术...
3. 线程安全:项目中使用了Java的synchronized关键字和Lock接口来确保线程安全。这样可以避免多个线程同时访问共享资源,从而避免数据不一致和其他潜在问题。 4. 基于Http协议:项目使用了Java的HttpURLConnection...
Java提供了多种同步机制,包括synchronized关键字、Lock接口和Semaphore类。 线程间通信(Inter-Thread Communication):线程间通信允许线程之间共享信息和协作。 线程池(ThreadPool):线程池是一种管理线程资源...
Java线程指南 线程安全与不安全 线程同步synchronized和volatile 线程协作-生产者/消费者模式 Timer和TimerTask 线程池 Callable和Future 锁对象Lock-同步问题更完美的处理方式 Condition-线程通信更高效的方式