`
javawebsoa
  • 浏览: 417855 次
社区版块
存档分类
最新评论

(3)传统线程互斥技术 synchronized 经典解析。【线程同步】 外加【内部类与外部类 】

 
阅读更多
(1)首先回顾:内部类与外部类

点击打开链接


(2)线程同步(这一段文字源于借鉴)
当多个线程访问同一个数据时,非常容易出现线程安全问题。

这时候就需要用线程同步 Case:银行取钱问题,有以下步骤:
A、用户输入账户、密码,系统判断是否登录成功
B、用户输入取款金额
C、系统判断取款金额是否大于现有金额
D、如果金额大于取款金额,就成功,否则提示小于余额

现在模拟2个人同时对一个账户取款,多线程操作就会出现问题。这时候需要同步才行;
同步代码块: synchronized (object) { //同步代码 } Java多线程支持方法同步,方法同步只需用用synchronized来修饰方法即可,那么这个方法就是同步方法了。
对于同步方法而言,无需显示指定同步监视器,同步方法监视器就是本身this
同步方法: public synchronized void editByThread() { //doSomething } 需要用同步方法的类具有以下特征:
A、该类的对象可以被多个线程访问
B、每个线程调用对象的任意都可以正常的结束,返回正常结果
C、每个线程调用对象的任意方法后,该对象状态保持合理状态


不可变类总是线程安全的,因为它的对象状态是不可改变的,但可变类对象需要额外的方法来保证线程安全。
例如Account就是一个可变类,它的money就是可变的,当2个线程同时修改money时,程序就会出现异常或错误。
所以要对Account设置为线程安全的,那么就需要用到同步synchronized关键字。

下面的方法用synchronized同步关键字修饰,那么这个方法就是一个同步的方法。
这样就只能有一个线程可以访问这个方法, 在当前线程调用这个方法时,此方法是被锁状态,同步监视器是this。
只有当此方法修改完毕后其他线程才能调用此方法。
这样就可以保证线程的安全,处理多线程并发取钱的的安全问题。
public synchronized void drawMoney(double money) { //取钱操作 }
注意:synchronized可以修饰方法、代码块,但不能修饰属性、构造方法 可变类的线程安全是以降低程序的运行效率为代价,
为了减少线程安全所带来的负面影响,
可以采用以下策略:
A、不要对线程安全类的所有方法都采用同步模式,只对那些会改变竞争资源(共享资源)的方法进行同步。
B、如果可变类有2中运行环境:单线程环境和多线程环境,则应该为该可变提供2种版本;线程安全的和非线程安全的版本。

在单线程下采用非线程安全的提高运行效率保证性能,在多线程环境下采用线程安全的控制安全性问题。
释放同步监视器的锁定 任何线程进入同步代码块、同步方法之前,必须先获得对同步监视器的锁定,
那么何时会释放对同步监视器锁定? 程序无法显示的释放对同步监视器的锁定,线程可以通过以下方式释放锁定:
A、当线程的同步方法、同步代码库执行结束,就可以释放同步监视器
B、当线程在同步代码库、方法中遇到break、return终止代码的运行,也可释放
C、当线程在同步代码库、同步方法中遇到未处理的Error、Exception,导致该代码结束也可释放同步监视器
D、当线程在同步代码库、同步方法中,程序执行了同步监视器对象的wait方法,导致方法暂停,释放同步监视器

下面情况不会释放同步监视器:
A、当线程在执行同步代码库、同步方法时,程序调用了Thread.sleep()/Thread.yield()方法来暂停当前程序,当前程序不会释放同步监视器
B、当线程在执行同步代码库、同步方法时,其他线程调用了该线程的suspend方法将该线程挂起,该线程不会释放同步监视器。

注意尽量避免使用suspend、resume


以下是向 传智播客 张孝祥老师 的学习总结
1,代码出错分析:


上面代码报错,解决方案:


方法被调用的时候 一定是 某对象身上的方法,因为他不是静态方法,一定是创建了外部类的对象,
这个方法运行的时候,一定有一个对象,
new Outputer();//这个家伙一定要找一个外部类,也就是 谁调用了 init()方法。



上面代码,出现:中间代码被打乱,也就是多线程喜欢出的问题。一个事情没有办完,另一个事件就会发生,为了防止这个问题,我们用同步技术。
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();// 此句为 换行。


这段代码要实现原子性。就是说,当有一个县城来执行我的时候,别的县城不能够来执行我;就像厕所里的坑一样,嘎嘎
synchronized(name){// 起不到效果,互斥一定要做到同一个对象。
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();// 此句为 换行。
}
分析:两个线程同时用到了outputer对象:


如果改成:new Outputer().output("lihuoming");就有问题了。注意:一定要使用同一个对象。不过:xxx可以用this关键字来代替,不然就多此一举了。




2,倘若我要保护output整个方法的代码,怎么办:那就在这个方法里面用:synchronized这个关键字。


下面代码也是灭有问题的,保护的地区不一样,不过也都是同一个对象:


3, 下面代码 问:方法1,2能否分别和方法3 同步???


结果:不可以同步!!!


方法1和方法3没有同步,类的字节码在内存中也算是一个对像,静态方法执行的时候不用创建实例对象,只有 字节码对象这个说法了,要想让他们同步:方法1也必须用字节码,this改为:
public void output(String name) {
int len = name.length();
synchronized(Outputer.class){// 起不到效果,互斥一定要做到同一个对象。
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();// 此句为 换行。
}
}


就可以同步了。


分享到:
评论

相关推荐

    操作系统实验 多线程同步与互斥 java编写 有界面

    操作系统实验是计算机科学教育中的重要组成部分,它帮助学生理解和掌握操作系统的基本原理,特别是多线程同步与互斥的概念。在Java编程环境下,这些概念可以通过实际的代码实现来深入理解。 多线程是现代操作系统中...

    实例讲述线程的同步互斥

    **线程互斥** 是线程同步的一种特殊形式,确保同一时间只有一个线程能够访问特定的资源。互斥锁是实现线程互斥的常用工具。当一个线程获取了互斥锁后,其他试图获取该锁的线程会被阻塞,直到持有锁的线程释放它。在...

    JAVA实现线程间同步与互斥生产者消费者问题

    本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费者问题是经典的并发问题之一,它涉及到两个类型的线程:生产者和消费者。生产者负责生成数据(产品),而消费者则...

    java 多线程synchronized互斥锁demo

    总结来说,Java中的`synchronized`关键字是实现线程同步的关键,它通过互斥锁确保对共享资源的访问是线程安全的。在多线程编程中,合理使用`synchronized`可以有效避免竞态条件,保证程序的正确性和稳定性。对于...

    线程间互斥2

    在Java中,我们可以使用`synchronized`关键字或ReentrantLock等类来实现线程互斥。 1. **synchronized 关键字**:synchronized 可以用来修饰方法或代码块,当一个线程进入一个由 synchronized 修饰的方法或代码块时...

    第20章 Part3 多线程互斥与协作.pdf

    ### 第20章 Part3:多线程互斥与协作 #### 一、互斥(Mutual Exclusion) 互斥是指在线程编程中确保多个线程不会同时访问同一资源的技术。这种技术非常重要,因为如果不加以控制,多个线程对共享资源的并发访问...

    java的线程同步机制synchronized关键字的理解_.docx

    Java 线程同步机制中 synchronized 关键字的理解 Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 ...

    线程同步面试题深入解析

    在Java中,线程同步主要通过`synchronized`关键字来实现,防止多个线程同时访问临界区,以避免出现不可预期的结果。 1. **synchronized修饰同步方法** 使用`synchronized`关键字修饰的方法称为同步方法。同步方法...

    线程 互斥.rar案例

    线程互斥是多线程编程中的一个关键概念,它涉及到如何在并发环境中确保资源的安全访问,以防止数据不一致性和竞态条件的发生。在这个"线程 互斥.rar"案例中,我们很可能会探讨如何在编程中实现线程间的互斥机制,以...

    详细解读java同步之synchronized解析

    【Java同步之synchronized解析】 Java中的`synchronized`关键字是实现多线程同步的重要机制,它确保了在并发环境中对共享资源的访问是线程安全的。以下是对`synchronized`的详细解读: ### 1. synchronized的特性 ...

    Java语言中的线程同步互斥研究.pdf

    线程同步互斥机制的实现可以通过使用经典操作系统进程同步互斥算法来实现,例如使用信号量、监视器、信号灯等机制。这些机制可以确保线程之间的协调工作和资源的互斥访问。 8. 结论 线程同步互斥机制是Java语言中...

    线程互斥和同步代码样本滴水三期信号量布置的作业

    在实际应用中,线程互斥和同步不仅可以防止数据竞争,还可以用于实现线程间的协作,比如生产者-消费者问题、读者-写者问题等经典并发模型。在这些模型中,线程通过互斥和同步机制,遵循一定的规则进行通信和协调,...

    正确使用多线程同步锁@synchronized()1

    在iOS开发中,多线程同步是保证代码安全的关键技术之一。`@synchronized`关键字是Apple提供的一种简便的同步机制,它可以帮助开发者确保在多线程环境下对共享资源进行原子性操作,防止数据竞争问题。本文将深入探讨`...

    线程进程互斥锁

    3. **线程与进程互斥锁的应用**: - **文件操作**:在多个线程或进程中,如果需要对同一个文件进行读写操作,使用互斥锁可以防止数据的混乱,确保每次只有一个线程或进程进行读写。 - **全局变量**:当多个线程...

    线程同步互斥

    ### 线程同步互斥知识点详解 #### 一、线程同步互斥的重要性 在多线程编程中,为了提高程序的运行效率,我们常常会利用多线程技术进行并行处理。然而,线程间共享数据的操作可能会引发竞态条件(Race Condition)...

    Java实现的进程同步与互斥(PV)

    在计算机科学中,进程同步与互斥是多线程编程中的关键概念,它们确保了多个线程在访问共享资源时的正确性和一致性。本主题主要关注如何使用Java语言实现这些概念,特别是通过PV操作(即P操作和V操作),这是荷兰...

    线程同步的三种方式,事件,关键代码段,互斥变量,3个示例工程

    在多线程编程中,线程同步是一种重要的技术,用于协调多个并发执行的线程,以确保它们能正确地共享资源,避免数据竞争和其他潜在的并发问题。在Java、C++、C#等编程语言中,有多种实现线程同步的方法。本篇文章将...

    进程同步互斥

    在操作系统中,进程同步与互斥是两个关键概念,它们涉及到多线程环境下的资源管理和程序执行顺序。在这个Java课程设计任务中,我们将探讨如何利用Java语言实现对进程的同步互斥控制,以便理解并模拟操作系统的核心...

    操作系统进程同步和互斥的实验报告

    在Java代码实现中,使用了`SyncStack`类作为同步栈,包含`push`和`pop`方法,这两个方法被声明为`synchronized`以实现互斥访问。`WoTou`类代表生产者产生的产品。在`push`方法中,当缓冲区满时,生产者调用`wait()`...

    Java多线程同步具体实例讲解 .doc

    本文将通过一个具体的售票系统实例来深入解析Java中的线程同步。 首先,我们要了解Java中的关键字`synchronized`,它是实现线程同步的主要手段。当一个方法或代码块被`synchronized`修饰时,同一时间只有一个线程...

Global site tag (gtag.js) - Google Analytics