可重入锁|信号量
ReentrantLock和Semaphore
- 抢占式
- 公平非公平在于队列同步器判断是否有前驱结点
- 同一个线程可获取锁多次
CountDownLatch
- 非抢占式
子父线程等待的FutureTask
JDK简易版,很多细节就不写了,意义不是很大,还有很多面试人会问cancel,我也不太清楚有啥用,一个中断和非中断取消,
中断立即结束当前callable任务,get是个持续过程,构造死循环单出口状态!
package practise;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.LockSupport;
public class FutureTask<V> implements Runnable, Future<V> {
private Node waiter;
private V result;
private Callable<V> callable;
/**
*
*/
public FutureTask(Callable<V> callable) {
this.callable = callable;
}
static class Node {
Thread thread;
/**
*
*/
public Node() {
thread = Thread.currentThread();
}
}
/**
* @see java.util.concurrent.Future#cancel(boolean)
*/
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
/**
* @see java.util.concurrent.Future#isCancelled()
*/
@Override
public boolean isCancelled() {
return false;
}
/**
* @see java.util.concurrent.Future#isDone()
*/
@Override
public boolean isDone() {
return false;
}
/**
* @see java.util.concurrent.Future#get()
*/
@Override
public V get() throws InterruptedException, ExecutionException {
//防止并发子线程任务执行完后,父线程才执行阻塞操作,采用死循环【而且还需要设置状态,比较懒不写了】
if (waiter == null) {
waiter = new Node();
}
LockSupport.park(this);
return result;
}
/**
* @see java.util.concurrent.Future#get(long, java.util.concurrent.TimeUnit)
*/
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException,
TimeoutException {
return null;
}
/**
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
try {
result = callable.call();
} catch (Exception e) {
} finally {
//结束当前等待父线程
if (waiter != null) {
LockSupport.unpark(waiter.thread);
}
}
}
public static void main(String[] args) {
FutureTask<String> task = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(1000 * 5);
return "finish";
}
});
new Thread(task).start();
try {
System.out.println(task.get());
} catch (InterruptedException | ExecutionException e) {
}
System.out.println(Thread.currentThread() + "finish");
}
}
join无返回形式
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000 * 5);
System.out.println("finish");
} catch (InterruptedException e) {
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + "finish");
join原理
if (millis == 0) {
while (isAlive()) {
wait(0);
}
}
CountDownLatch使用
CountDownLatch latch=new CountDownLatch(1);
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000 * 5);
System.out.println("finish");
latch.countDown();
} catch (InterruptedException e) {
}
}
});
try {
latch.await();
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + "finish");
CyclicBarrier
https://www.cnblogs.com/leesf456/p/5392816.html
线程枚举状态
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
上面普通操作导致线程的改变
sleep, 进入TIMED_WAITING状态,不出让锁
wait, 进入TIMED_WAITING状态,出让锁,并进入对象的等待队列
park, 进入WAITING状态,对比wait不需要获得锁就可以让线程WAITING,通过unpark唤醒
interrupt, 只是给线程发个信号,如果在wait, sleep会收到exception【这个有点疑问,异常就执行完】
yeild, 在操作系统层面让线程从running变成ready状态,等待继续被调度。在jvm的线程状态还是RUNNABLE