synchronized

【Java并发基础】死锁

寵の児 提交于 2020-01-23 00:55:33
前言 我们使用加锁机制来保证线程安全,但是如果过度地使用加锁,则可能会导致死锁。下面将介绍关于死锁的相关知识以及我们在编写程序时如何预防死锁。 什么是死锁 学习操作系统时,给出死锁的定义为两个或两个以上的线程在执行过程中,由于竞争资源而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。简化一点说就是: 一组相互竞争资源的线程因为互相等待,导致“永久”阻塞的现象 。 下面我们通过一个转账例子来深入理解死锁。 class Account { private int balance; // 转账 void transfer(Account target, int amt){ if (this.balance > amt) { this.balance -= amt; target.balance += amt; } } } 为了使以上转账方法transfer()不存在并发问题,很快地我们可以想使用Java的synchronized修饰transfer方法,于是代码如下: class Account { private int balance; // 转账 synchronized void transfer(Account target, int amt){ if (this.balance > amt) { this.balance -= amt; target.balance

多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(下)

有些话、适合烂在心里 提交于 2020-01-23 00:34:06
同系列阅读: 多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(上) , 多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(中) 前两篇简单介绍了线程同步lock,Monitor,同步事件EventWaitHandler,互斥体Mutex的基本用法,在此基础上,我们对它们用法进行比较,并给出什么时候需要锁什么时候不需要的几点建议。 最后,介绍几个FCL中线程安全的类,集合类的锁定方式等,做为对线程同步系列的完善和补充。 1.几种同步方法的区别 lock和Monitor是.NET用一个特殊结构实现的,Monitor对象是完全托管的、完全可移植的,并且在操作系统资源要求方面可能更为有效, 同步速度较快 ,但 不能跨进程同步 。lock(Monitor.Enter和Monitor.Exit方法的封装),主要作用是锁定临界区,使临界区代码只能被获得锁的线程执行。Monitor.Wait和Monitor.Pulse用于线程同步,类似信号操作,个人感觉使用比较复杂,容易造成死锁。 互斥体Mutex和事件对象EventWaitHandler属于内核对象,利用内核对象进行线程同步,线程必须要在用户模式和内核模式间切换,所以 一般效率很低 ,但利用互斥对象和事件对象这样的内核对象,可以 在多个进程中的各个线程间进行同步 。 互斥体

Java面试 4.10 多线程

不想你离开。 提交于 2020-01-22 22:25:24
4.10.1 什么是线程?它与进程有什么区别?为什么要使用多线程 线程是指程序在执行过程中,能够执行程序代码的一个执行单元。 进程是指一段正在执行的程序。而线程有时也被称为轻量级进程,它是程序执行的最小单元,一个进程可以拥有多个线程,各个线程之间共享程序的内存空间(代码段、数据段和堆空间)及一些进程级的资源(例如打开的文件),但是各个线程拥有自己的栈空间。 在操作系统级别上,程序的执行都是以进程为单位的,而每个进程中通常都会有多个线程互不影响地并发执行,那么为什么要使用多线程呢?其实,多线程的使用为程序研发带来了巨大的便利,具体而言,有以下几个方面的内容: 1)使用多线程可以减少程序的响应时间。在单线程(单线程指的是程序执行过程中只有一个有效操作的序列,不同操作之间都有明确的执行先后顺序)的情况下,如果某个操作很耗时,或者陷入长时间的等待(如等待网络响应),此时程序将不会响应鼠标和键盘等操作,使用多线程后,可以把这个耗时的线程分配到一个单独的线程去执行,从而使程序具备了更好的交互性。 2)与进程相比,线程的创建和切换开销更小。由于启动一个新的线程必须给这个线程分配独立的地址空间,建立许多数据结构来维护线程代码段、数据段等信息,而运行于同一进程内的线程共享代码段、数据段,线程的启动或切换的开销比进程要少很多。同时多线程在数据共享方面效率非常高。 3)多 CPU

面试-锁

佐手、 提交于 2020-01-22 21:43:44
一、请你简述一下synchronized与java.util.concurrent.locks.Lock的相同之处和不同之处? 答:相同点:Lock能完成synchronized所实现的所有功能; 不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动会释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。 二、Java中如何确保n个线程可以访问n个资源,但同时又不导致死锁? 答:使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。预防死锁,预先破坏产生死锁的四个条件。互斥不可能破坏,所以有如下三种方法: ①破坏请求和保持条件,进程必须等所有要请求的资源都空闲时才能申请资源,这种方法会使资源浪费严重。允许进程获取初期所需资源后,便开始运行,运行过程中再逐步释放自己占有的资源,比如有一个进程的任务是把数据复制到磁盘中再打印,前期只需获得磁盘资源而不需要获得打印机资源,待复制完毕后在释放掉磁盘资源。 ②破坏不可抢占条件,这种方法代价大,实现复杂。 ③破坏循环等待条件,对各进程请求资源的顺序做一个规定,避免相互等待。 三、请问什么是死锁? 答

如何在匿名thread子类中保证线程安全

微笑、不失礼 提交于 2020-01-22 13:04:58
在做性能测试的过程中,我写了两个虚拟类 ThreadLimitTimeCount 和 ThreadLimitTimesCount 做框架,通过对线程的标记来完成超时请求的记录。旧方法如下: @Override protected void after() { requestMark.addAll(marks); marks = new ArrayList<>(); GCThread.stop(); synchronized (this.getClass()) { if (countDownLatch.getCount() == 0 && requestMark.size() != 0) { Save.saveStringList(requestMark, MARK_Path.replace(LONG_Path, EMPTY) + Time.getDate().replace(SPACE_1, CONNECTOR)); requestMark = new Vector<>(); } } } 其中我用了 synchronized 关键字同步,但是在匿名类的单元测试中出现一个BUG,匿名类中没有实现 clone() 方法,也不能直接使用深拷贝方法,导致无法直接复制对象,所以我创建了多个功能相同的匿名线程类。问题来了,在代码执行过程中,偶然会出现记录 markrequest

ConcurrentModificationException even with using Collections.sychronizedMap on a LinkedHashMap [duplicate]

余生长醉 提交于 2020-01-22 12:40:51
问题 This question already has answers here : Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop (24 answers) Why is a ConcurrentModificationException thrown and how to debug it (7 answers) ConcurrentModificationException despite using synchronized (3 answers) Closed 10 months ago . I'm using a Map object in my class that I've synchronized with Collections.synchronizedMap() for a LinkedHashMap like so: private GameObjectManager(){ gameObjects =

Java 多线程(二)

ぐ巨炮叔叔 提交于 2020-01-22 12:36:27
Java 多线程(二) 线程同步 Lock 同步锁 线程同步 线程同步的基本方法主要为使用synchronized 关键字来修饰代码块或方法。 实例如下 synchronized ( obj ) //obj成为同步监视器,通常为要被并发访问的共享资源 { } public synchronized void do ( ) //synchronized修饰方法,则默认的同步监视器为this,因此,任何时刻只有一个线程能使用do()访问this。 { } Lock 同步锁 除了synchronized关键字外,Java还提供了一种锁机制。 通过锁机制,可以更灵活地控制共享资源地同步。 下面举个例子: 首先定义一个共享资源类Info public class Info { private int amount ; public Info ( int amount ) { this . amount = amount ; } public void minus ( int a ) //定义一个减少amount的方法 { System . out . println ( "the amount now is " + this . amount ) ; this . amount -= a ; System . out . println ( "the amount now is " +

What does “synchronized” mean in Java? [duplicate]

人走茶凉 提交于 2020-01-22 10:43:22
问题 This question already has answers here : What does 'synchronized' mean? (16 answers) Closed 2 years ago . I have been trying to learn design patterns. This site uses the synchronized keyword, but I don't understand what it does. I searched on the net and found that it is somewhat related to multi-threading and memory, but I am a mechanical engineer and don't understand what that means. Can anybody please help me understand threads and the synchronized keyword? 回答1: There is no synchronized

011程序、进程、线程的概念+Java中多线程的创建和使用+线程的生命周期+线程的同步+线程的死锁问题

孤街浪徒 提交于 2020-01-21 23:54:38
一.程序、进程、线程的概念 基本概念 程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。 进程(process)是程序的一次执行过程,或是正在运行的一个程序。动态过程:有它自身的产生、存在和消亡的过程。如:运行中的QQ,运行中的MP3播放器;程序是静态的,进程是动态的。 线程(thread)进程可进一步细化为线程,是一个程序内部的一条执行路径。若一个程序可同一时间执行多个线程,就是支持多线程的。 何时需要多线程:程序需要同时执行两个或多个任务;程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等:需要一些后台运行的程序时。 二.Java中多线程的创建和使用 多线程的创建和启动 Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread类来实现。 Thread类的特性:每个线程都是通过某个特定的Thread对象的run()方法来完成操作的,经常把run()方法的主体称为线程体。通过该Thread对象的start()方法来调用这个线程。 背景:只使用单个线程完成多个任务(调用多个方法),肯定比多个线程来完成用的时间更短,为何仍然需要多线程呢? 多线程程序的优点:提高应用程序的响应。对图形化界面更有意义,可增强用户体验。提高计算机系统CPU的利用率。 改善程序结构

Java Synchronized method…not synchronized

天涯浪子 提交于 2020-01-21 17:25:45
问题 For my current java exercise, I have to get mail from 2 different gmail accounts. I have done this by creating new instances of my gmail class. The gmail class extends thread, and within it there is a synchronized method readMail() which gets the mail and prints it. This readMail method is called by the run method in a while(true) loop, and then it sleeps for 30 seconds, the idea being that it gets mail every 30 seconds. However, the synchronized method does not seem to work. The threads