1.没有拿到锁的线程,将会被阻塞,也就是说它将在去获取锁的那块代码那里等待到得到锁,直到得到锁后才会继续执行下面的方法。
2.通过setPriority来设置线程的优先级
3.synchronized 是对象锁,拥有重入锁的功能,也就是当一个线程通过synchronized得到对象锁后再次请求该对象的锁是可以得到的,如调用该对象的其他synchronized依然可以拿到锁。当一个线程持有对象锁的时候,就持有所有synchronized修饰的该对象的实例方法,其他的线程在这时候无法使用,直到该线程释放锁。
4.同步不能被继承,所有对于父类的具有synchronized修饰的方法,子类也要使用synchronized修饰才是同步方法,否则不会继承父类的同步修饰。synchronized修饰方法的时候持有的是调用该方法的对象的锁。
5.synchronized修饰实例方法和synchronized(this){}代码块是一样的,都是持有调用的对象锁。但是synchronized是对整个方法里面的代码进行同步,而synchronized(){}只针对{}代码块中的代码进行同步控制。
6.对于类方法的同步,持有的是当前对象的类锁,和当前对象锁不一样,它们没有关系,即类锁影响的是static synchronized修饰的类方法和synchronized(Object.class){}中的同步代码块synchronized(Object.class){},当一个方法被static修饰就说明是类方法,那么在这个方法中修饰的同步代码块的对象锁是类对象锁,synchronized(Object.class){},因此只能是Object.class而不能是this。
7.Thread.join();在这里等待直到此线程(调用join的线程)完成,Thread.join(long time),等待此线程一段时间,如果还没有完成则往下执行,内部是wait();会释放当前锁。
8.Thread.sleep(long time),等待,不释放锁。
9.ThreadLocal ,对于同一个ThreadLocal不同的线程有在ThreadLocal中有不同的存储值空间。每个线程可通过set和get来设置要存储的值和取出存储的值。
10.finally是对try中的执行体进行反馈,不管是否出现异常都应该去对try中的执行体做一个最后的处理
11.ReentrantLock也是一种锁机制,当Condition.await被调用时,当前的线程就会释放锁,并在调用处一直等待,直到有其他线程调用了Condition.sign或者signAll方法来唤醒它。
12.所有锁机制,在调用等待和通知之前必须拥有对象监视器,也就是要拿到锁,也就是当使用synchronized时这个调用必须是在synchronized方法或者块当中的,在ReentrantLock时是必须在ReentrantLock.lock()执行之后的,否则会报出无效监视器的异常。
13.公平锁是先来先得,先等先得,非公平锁是随机给的,有可能有些线程会一直拿不到锁,默认锁是非公平锁。在ReentrantLock(isFair)构造时传入一个boolean fair的值,来让此锁成为公平锁或者非公平锁。
14.ReentrantReadWriteLock,读写锁,当一个线程在使用读锁未释放时,另一个线程也想要拿读锁则可以直接拿到而不用等待。当一个线程在使用写锁未释放时,另一个线程在想要拿写锁时,需要等待当前线程释放写锁才能拿到。当一个线程在使用读锁时,另一个线程想要拿写锁,也得等待直到读锁释放才能拿到写锁,当一个线程在使用写锁时,另一个线程想拿读锁也需要等待写锁释放才能拿到读锁。归总就是:读读不互斥,写写,读写,写读都互斥。
15.Timer定时器,TimerTask定时器任务,Timer可以让TimerTask在将来的某个时间或者延迟多少时间后执行。Timer跟TimerTask就像Thread和Runnable的关系。Timer t=new Timer();创建一个普通的定时器,Timer t=new Timer(boolean isDaemon);,创建一个是否是守护的timer,守护timer是跟应用的生命周期一样长,如果应用结束了则timer的任务也都清空,如果在应用还没有结束前,timer中的任务时间到达则任务可以正常执行。timer.cancel(),可以将当前的所有定时器中的任务都停止。task.cancel()可以取消某个任务。
-------------------java.util.concurrent--------------------
16.BlockingQueue,这是一个线程安全的队列接口。
ArrayBlockingQueue基于数组的队列,初始化时需要指定容量大小。
DelayQueue延迟队列,放入此队列的对象需要实现Delayed接口,并在Delayed的getDelay方法中计算仍需要延迟的时长,这个方法会被队列不停调用以判断是否延迟结束。放入此队列的对象只有当它延迟结束后才能被取走。
LinkedBlockingQueue以FIFO先进先出的方式存储对象
PriorityBlockingQueue具有优先级别的队列,存入的对象必须实现java.lang.Comparable来完成优先级定义。
SynchronousQueue同步队列,只能容纳一个元素,当为空时,取出元素被阻塞直到有元素被放入,当不为空时,放入元素被阻塞,直到为空。
17,BlockingDeque双端阻塞队列,需要在两端进行插入和提取的需求
LinkedBlockingDeque链表式
18.ConcurrentMap可以对插入和提取进行并发访问的Map
ConcurrentHashMap
19.闭锁CountDownLatch
20.CyclicBarrier栅栏,有线程必须等待的一个栅栏,直到所有线程都到达这里,然后
所有线程才可以继续做其他事情,CyclicBarrier.await()来等待所有线程到达再继续,初始化接收一个int来判断所有线程是否都已到达。CyclicBarrier在构造的时候也可以传入一个Runnable, CyclicBarrier(int,Runnable)使得当所以线程都到达栅栏后就会去执行的一个Action.
21.Exchanger,交换机,表示一种两个线程可以进行互相交换对象的会和点。this.exchanger.exchange(this.object);
22.信号量 Semaphore,是一个计数信号量。具备两个主要方法:
acquire()
release()
计数信号量由一个指定数量的 "许可" 初始化。每调用一次 acquire(),一个许可会被调用线
程取走。每调用一次 release(),一个许可会被返还给信号量。
Semaphore 用法, 保护一个重要(代码)部分防止一次超过 N 个线程进入。如果你将信号量用于保护一个重要部分,试图进入这一部分的代码通常会首先尝试获得一个
许可,然后才能进入重要部分(代码块),执行完之后,再把许可释放掉。比如这样:
Semaphore semaphore = new Semaphore(1);
//critical section
semaphore.acquire();
...
semaphore.release();
23.ExecutorService,线程池
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
ExecutorService executorService2 = Executors.newFixedThreadPool(10);
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
实现有两个类,ThreadPoolExecutor,ScheduledExecutorService.
24.原子性
AtomicBoolean
AtomicInteger
AtomicLong
AtomicReference
方法:get(),set(),getAndSet()