java-多线程

介绍一下Syncronized锁。如果用这个关键字修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么?

修饰静态方法、修饰成员变量:相当于全局锁,相当于锁住了整个类。

synchronized(this)以及非static的synchronized方法(至于static synchronized方法请往下看),只能防止多个线程同时执行同一个对象的同步代码段

介绍一下volatile

保证可见性,有序性

当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。

在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。

而声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读

lock(防止指令重排序)

在执行程序时为了提高性能,编译器和处理器通常会对指令做重排序:

编译器重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序;

处理器重排序。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序;

多线程中的i++线程安全吗?为什么?

局部变量中安全,全局变量不安全。

i++不是原子性操作,相当于int tp1 = i; int tp2 = tp1+1; i = tp2; 

如何线程安全的实现一个计数器?

使用AtomicInteger 等原子类。

给i++加锁

线程同步有哪几种方式

1.同步方法

2.同步代码块  

3.使用特殊域变量(volatile)实现线程同步

4.使用重入锁实现线程同步 

5.使用局部变量实现线程同步 (使用ThreadLocal管理变量)

6.wait与notify

7.使用原子变量实现线程同步

concurrenthashmap有啥优势,1.7,1.8区别

http://www.importnew.com/23610.html

AQS(AbstractQueuedSynchronized)

Java并发之AQS详解 - CodesGeek - 博客园

CAS(Compare And Swap )

如果V值等于E值,则将V的值设为N。若V值和E值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。

通俗的理解就是CAS操作需要我们提供一个期望值,当期望值与当前线程的变量值相同时,说明还没线程修改该值,当前线程可以进行修改,也就是执行CAS操作,但如果期望值与当前线程不符,则说明该值已被其他线程修改,此时不执行更新操作,但可以选择重新读取该变量再尝试再次修改该变量,也可以放弃操作

ABA

比如说一个线程one从内存位置V中取出A,这时候另一个线程two也从内存中取出A,并且two进行了一些操作变成了B,然后two又将V位置的数据变成A,这时候线程one进行CAS操作发现内存中仍然是A,然后one操作成功。尽管线程one的CAS操作成功,但是不代表这个过程就是没有问题的。如果链表的头在变化了两次后恢复了原值,但是不代表链表就没有变化。因此前面提到的原子操作。

各种乐观锁的实现中通常都会用版本戳version来对记录或对象标记,避免并发操作带来的问题。

线程安全的Map都有啥,Collections.synchronizedmap(),ConcurrentHashMap,Hashtable 底层实现

线程池运行流程,参数,策略

线程池相关笔记,线程池的实现?四种线程池?重要参数及原理?任务拒接策略有哪几种? - CSDN博客

synchronized,偏向锁,轻量级锁,重量级锁,锁膨胀机制

Synchronized的原理及自旋锁,偏向锁,轻量级锁,重量级锁的区别 - CSDN博客

wait方法底层原理 join,notify,notifyall

多线程(二):详细描述wait、notify/notifyAll、join及底层实现 - CSDN博客

线程池原理

理解线程池的原理 - CSDN博客

讲一下非公平锁和公平锁在reetrantlock里的实现。

FairSync 公平锁 

公平锁就是每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中获取,

讲一下synchronized,可重入怎么实现

Java中一个线程在通过synchronized获取到一个对象的对象锁后会阻塞试图获取该对象锁的其他线程,但不会阻塞当前线程,也就是说synchronized代码块对当前线程来说是可重入的

多线程实现方法

继承Thread类创建线程类,重写run方法,run方法就是代表线程需要完成的任务,调用线程对象的start()来启动该线程,线程类已经继承了Thread类,所以不能再继承其他父类。   

实现Runnable接口创建线程类,定义Runnable实现类,重写run方法   

实现Callable接口,重写call()方法,call()作为线程的执行体,具有返回值   

线程池,使用线程池产生线程对象java.util.concurrent.ExecutorService、java.util.concurrent.Executors;

Synchronized和lock区别

Lock提供了synchronized关键字所不具备的主要特性有:

尝试非阻塞地获取锁boolean tryLock():当前线程尝试获取锁,如果这一时刻没有被其他线程获取到,则成功获取并持有锁       

能被中断地获取锁void lockInterruptibly():当获取到锁的线程被中断时,中断异常抛出同时会释放锁       

超时获取锁boolean trylock(long time, TimeUnit unit):在指定截止时间之前获取锁,如果在截止时间仍旧无法获取锁,则返回     

synchronized是JVM提供的加锁,悲观锁;lock是Java语言实现的,而且是乐观锁。   

ReentrantLock是基于AQS实现的,由于AQS是基于FIFO队列的实现

Java中都有什么锁

重量级锁、显式锁、并发容器、并发同步器、CAS、volatile、AQS等

可重入锁的设计思路是什么

可重入公平锁获取流程

在获取锁的时候,如果当前线程之前已经获取到了锁,就会把state加1,在释放锁的时候会先减1,这样就保证了同一个锁可以被同一个线程获取多次,而不会出现死锁的情况。这就是ReentrantLock的可重入性。

对于非公平锁而言,调用lock方法后,会先尝试抢占锁,在各种判断的时候会先忽略等待队列,如果锁可用,就会直接抢占使用。

乐观锁和悲观锁

悲观锁:假定会发生并发冲突,则屏蔽一切可能违反数据完整性的操作

乐观锁:假定不会发生并发冲突,只在数据提交时检查是否违反了数据完整性(不能解决脏读问题)

juc包内有哪些类

CountDownLatch 同步计数器,主要用于线程间的控制,但计数无法被重置,如果需要重置计数,请考虑使用 CyclicBarrier 。

线程池新任务到达时会先使用空闲线程还是加入阻塞队列

Java并发包里面的CountdownLatch怎么使用

这个类是一个同步计数器,主要用于线程间的控制,当CountDownLatch的count计数>0时,await()会造成阻塞,直到count变为0,await()结束阻塞,使用countDown()会让count减1。CountDownLatch的构造函数可以设置count值,当count=1时,它的作用类似于wait()和notify()的作用。如果我想让其他线程执行完指定程序,其他所有程序都执行结束后我再执行,这时可以用CountDownLatch,但计数无法被重置,如果需要重置计数,请考虑使用 CyclicBarrier 。

volatile和synchronized区别

volatile是变量修饰符,其修饰的变量具有可见性,Java的做法是将该变量的操作放在寄存器或者CPU缓存上进行,之后才会同步到主存,使用volatile修饰符的变量是直接读写主存,volatile不保证原子性,同时volatile禁止指令重排   

synchronized作用于一段代码或者方法,保证可见性,又保证原子性,可见性是synchronized或者Lock能保证通一个时刻只有一个线程获取锁然后执行不同代码,并且在释放锁之前会对变量的修改刷新到主存中去,原子性是指要么不执行,要执行就执行到底

一般线程和守护线程的区别

java中的线程分为两种:守护线程(Daemon)和用户线程(User)。

任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon(bool on);true则把该线程设置为守护线程,反之则为用户线程。Thread.setDaemon()必须在Thread.start()之前调用,否则运行时会抛出异常。

唯一的区别是判断虚拟机(JVM)何时离开,Daemon是为其他线程提供服务,如果全部的User Thread已经撤离,Daemon 没有可服务的线程,JVM撤离。也可以理解为守护线程是JVM自动创建的线程(但不一定),用户线程是程序创建的线程;比如JVM的垃圾回收线程是一个守护线程,当所有线程已经撤离,不再产生垃圾,守护线程自然就没事可干了,当垃圾回收线程是Java虚拟机上仅剩的线程时,Java虚拟机会自动离开。

你可能感兴趣的:(java-多线程)