synchronized

JAVA面试题-多线程(二)

你离开我真会死。 提交于 2020-01-14 12:17:56
1 . 并行和并发有什么区别? 并行:多个处理器或多核处理器同时处理多个任务。 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。 并发 = 两个队列和一台咖啡机。 并行 = 两个队列和两台咖啡机。 2. 线程和进程的区别? 一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的执行速度。 3. 守护线程是什么? 守护线程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。在 Java 中垃圾回收线程就是特殊的守护线程。 4. 创建线程有哪几种方式? 创建线程有三种方式: 继承 Thread 重写 run 方法; 实现 Runnable 接口; 实现 Callable 接口。 5. 说一下 runnable 和 callable 有什么区别? runnable 没有返回值,callable 可以拿到有返回值,callable 可以看作是 runnable 的补充。 6. 线程有哪些状态? 线程的状态: NEW 尚未启动 RUNNABLE 正在执行中 BLOCKED 阻塞的(被同步锁或者IO锁阻塞) WAITING 永久等待状态 TIMED_WAITING 等待指定的时间重新被唤醒的状态 TERMINATED 执行完成 7. sleep() 和 wait(

Java并发

假如想象 提交于 2020-01-14 12:15:42
编程问题中相当大的一部分都可以通过使用顺序编程来解决。 对于某些问题,如果能够并行地执行程序中的多个部分,则会变得非常方便。 并行编程可以使程序执行速度得到极大地提高。 当并行执行的任务彼此开始产生互相干涉时,实际的并发问题就会接踵而至。 Web服务器经常包含多个处理器,而并发是充分利用这些处理器的理想方式。 1.基本的线程机制 并发编程使我们可以将程序划分为多个分离的、独立运行的 任务 。 通过使用 多线程 机制,这些独立任务中的每一个都将由执行线程来驱动。 一个线程就是在 进程 中的一个单一的顺序控制流。 单个进程可以拥有多个并发执行的任务,但是你的程序使得每个任务都好像有自己的CPU一样。其底层机制是切分CPU时间,但通常你不需要考虑它。 在使用线程时,CPU将轮流给每个任务分配其占用时间,每个任务都觉得自己在一直占用CPU,但事实上CPU时间是划分成片段分配给了所有的任务。 多任务和多线程往往是使用多处理器系统的最合理方式。 1.1 定义任务 线程可以驱动任务,你需要一种描述任务的方式,这可以由 Runnable 接口来提供。 public class LiftOff implements Runnable { protected int countDown = 10; // Default private static int taskCount = 0; private

java编程思想-java中的并发(三)

僤鯓⒐⒋嵵緔 提交于 2020-01-14 12:13:09
三、终结任务 1. 在阻塞时终结 线程状态 一个线程可以处于以下四种状态之一: 1)新建(new):当线程被创建时,他只会短暂的处于这种状态。此时,他已经分配了必须的系统资源,并执行了初始化。此刻线程已经有资格获得CPU时间了,之后调度器将把这个线程转变为可运行zhuang't状态或阻塞状态。 2)就绪(Runnable):在这种状态下,只要调度器把时间片分配给线程,线程就可以运行。也就是说,在任意时刻,线程可以运行也可以不运行。只要调度器能分配时间片给线程,他就可以运行,这不同于死亡和阻塞状态。 3)阻塞(Blocked):线程能够运行,但是某个条件阻止他的运行。当线程处于阻塞状态时,调度器将忽略线程,不会分配给线程任何CPU时间。直到线程重新进入就绪状态,他才可能执行操作。 4)死亡(Dead):处于死亡或终止状态的线程将是不可调度的,并且再也不会得到CPU时间,它的任务已结束,或不再是可运行的。任务死亡的通常方式是从run()方法返回,但是任务的线程还可以被中断。 进入阻塞状态 一个任务进入阻塞状态,可能有如下原因: 1)通过调用sleep()使任务进入休眠状态,在这种情况下,任务在指定的时间内不会运行。 2)调用wait()使线程挂起,直到线程得到了notify()或notifyAll()消息(或者concurrent类库中等价的signal()或signalAll()消息

Java并发学习 & Executor学习 & 异常逃逸 & 同步互斥Best Practice & wait/notify, conditon#await/signal

陌路散爱 提交于 2020-01-14 12:11:55
看了这篇文章: http://www.ciaoshen.com/2016/10/28/tij4-21/ 有一些Java并发的内容,另外查了一些资料。 朴素的Thread 首先,Java中关于线程Thread最基本的事实是: 除非通过Native方法将本地线程加入JVM,创建线程唯一的方法就是“创建一个Thread类的实例对象,然后调用它的start()方法。” 其次,关于Thread对象实例的构造,需要注意,start()方法依赖于run()方法: 要么传递一个Runnable对象给构造器做参数。 要么重写Thread自己的run()方法。 第一种方法是实现Runnable接口。 注意, Runnable里面获取线程信息需要用 Thread.currentThread() package com.company; class MyRunnable implements Runnable { public void run() { try { Thread.sleep((long)(Math.random() % 5 * 1000 + 1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("Here is thread %d\n", Thread

JAVA面试题 请谈谈你对Sychronized关键字的理解?

别说谁变了你拦得住时间么 提交于 2020-01-14 12:05:46
面试官:sychronized关键字有哪些特性? 应聘者: 可以用来修饰方法; 可以用来修饰代码块; 可以用来修饰静态方法; 可以保证线程安全; 支持锁的重入; sychronized使用不当导致死锁; 了解sychronized之前,我们先来看一下几个常见的概念:内置锁、互斥锁、对象锁和类锁。 内置锁 在Java中每一个对象都可以作为同步的锁,那么这些锁就被称为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。 互斥锁 内置锁同时也是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,直到线程B抛出异常或者正常执行完毕释放这个锁;如果B线程不释放这个锁,那么A线程将永远等待下去。 对象锁和类锁 对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的。 对象锁是用于对象实例方法; 类锁是用于类的静态方法或者一个类的class对象上的 一个对象无论有多少个同步方法区,它们共用一把锁,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。

线程的同步控制synchronized和lock的对比和区别

戏子无情 提交于 2020-01-14 12:03:55
转载。 https://blog.csdn.net/wu1226419614/article/details/73740899 我们在面试的时候,时常被问到如何保证线程同步已经对共享资源的多线程编程。我们当然用同步代码块,同步方法,又或者是用java提供的锁机制来达到对共享资源变量的同步控制。 那么我们什么时候用synchronized,什么时候用lock,以及他们的区别是什么呢; 首先来说synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,通过对对象的头文件来操作,从而达到加锁和释放锁的目的。对象的头文件如下图: 那么synchronized的缺点是啥呢: 1)不能响应中断; 2)同一时刻不管是读还是写都只能有一个线程对共享资源操作,其他线程只能等待 3)锁的释放由虚拟机来完成,不用人工干预,不过此即使缺点也是优点,优点是不用担心会造成死锁,缺点是由可能获取到锁的线程阻塞之后其他线程会一直等待,性能不高。 而lock接口的提出就是为了完善synchronized的不完美的,首先lock是基于jdk层面实现的接口,和虚拟机层面不是一个概念;其次对于lock对象中的多个方法的调用,可以灵活控制对共享资源变量的操作,不管是读操作还是写操作; lock接口的关系图:

Does Java synchronized keyword flush the cache?

狂风中的少年 提交于 2020-01-14 08:20:11
问题 Java 5 and above only. Assume a multiprocessor shared-memory computer (you're probably using one right now). Here is a code for lazy initialization of a singleton: public final class MySingleton { private static MySingleton instance = null; private MySingleton() { } public static MySingleton getInstance() { if (instance == null) { synchronized (MySingleton.class) { if (instance == null) { instance = new MySingleton(); } } } return instance; } } Does instance have to be declared volatile in

java基础 锁

喜夏-厌秋 提交于 2020-01-14 07:50:47
一、乐观锁/悲观锁 乐观锁与悲观锁并不是特指某两种类型的锁,是人们定义出来的概念或思想,主要是指看待并发同步的角度。 (1)乐观锁: 每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。 乐观锁适用于多读的应用类型 ,这样可以提高吞吐量,在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS(Compare and Swap 比较并交换)实现的。 ①数据版本机制   实现数据版本一般有两种,第一种是使用版本号,第二种是使用时间戳。以版本号方式为例。   版本号方式:一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加1。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。 核心SQL代码: update table set xxx=#{xxx}, version=version+1 where id=#{id} and version=#{version}; ② CAS操作   CAS(Compare and Swap 比较并交换)

How do I conditionally lock in Java?

元气小坏坏 提交于 2020-01-14 05:03:14
问题 I have been making use of Java's synchronized blocks to make parts of my code thread safe. I am porting a data structure to java that can usually use synchronized blocks, but I don't always know how to use them in a typical Java way. Here is an example of one scenario: myMethod (Bool useLock) { if (useLock) { //locks the following section of code until unlocked. lockObject.lock(); } //do more stuff.... if (useLock) { //unlocks exclusive control of code. lockObject.unlock(); } } How do I do an

多线程的实现及其特点

蓝咒 提交于 2020-01-14 04:51:34
线程是比进程更小的执行单位。多线程:指在同一个程序中同时存在几个执行体,按几条不同的执行路径共同工作的情况。 线程的的状态与生命周期: (1)线程的5种状态:新建、就绪、运行、阻塞和消亡。 新建状态:当一个线程对象被声明并创建后即处于新建状态。可通过start()方法进入就绪状态。 就绪状态:进入线程队列排队等待系统为它分配CPU,一旦获得了CPU ,该线程就进入运行状态。 运行状态:自动执行自己的run方法中的代码。 阻塞状态:一个正在执行的线程在某些特殊情况下,如执行了suspend、join或sleep方法,或等待I/O设备的使用权,那么它将让出CPU并暂时中止自己的执行,进入阻塞状态。只有当引起阻塞的原因被消除时,线程才可以转入就绪状态。 消亡状态:处于消亡状态的线程不具有继续运行的能力。 实现多线程的两种方法: (1) 继承Thread类 (Thread类实现了Runnable接口) (2) 实现Runnable接口 (只有一个方法run()) 建立Thread子类和实现Runnable接口都可以创建多线程。但使用Runnable接口可以轻松实现多个线程共享相同数据,只要用同一个实现了Runnable接口的类的对象作为参数创建多个线程就可以了。 多线程的同步控制 在任何情况下,只可以有一个线程调用特定对象的synchronized