线程同步方式
线程同步
- 线程获取锁图解
- 第一种
- synchronized同步的方法
-
即有synchronized关键字修饰的方法.原因:java的每个对象都有一个内置锁,当用synchronized 修饰对象的方法的时候,内置锁会保护整个方法,调用之前,需要获取内置锁,否则就处于阻塞状态
-
状态变化:
1.成功获取锁的 NEW(创建)-->RUNNABLE(就绪状态)-->(getLock=true)Running(运行状态)---> Dead(死亡)
2.阻塞的 NEW(创建)-->RUNNABLE(就绪状态)-->(getLock=false)Blocked(阻塞状态(sleep(),wait(),join()))--->Running(运行状态)-->Dead(死亡)
- 图解
public class Lock {
public synchronized sayHelloWorld(){
System.out.println("Hello World");
}
}
-
第二种
-
使用特殊域变量(volatile)实现线程同步
-
第三种
-
使用重入锁实现线程同步
-
第四种
-
使用局部变量实现线程同步 (常用:ThreadLocal 类的常用方法)
-
第五种
-
使用阻塞队列实现线程同步
-第六种
-
使用原子变量实现线程同步(java 并发包 :java.util.concurrent.atomic)
多线程同步方法
public class Test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(new MyRunnable(latch));
thread.start();
}
//使用await()来阻塞线程迫使主线程等待异步线程全部执行 countDown 计数器归零.
latch.await();
}
static class MyRunnable implements Runnable {
private CountDownLatch countDownLatch;
public MyRunnable(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("附加线程开始."+Thread.currentThread().getId());
try {
//模拟异步线程 do something.....
Random random=new Random();
Thread.sleep(random.nextInt(5)*1000);
//执行完 计数器减一.
countDownLatch.countDown();
System.out.println("附加线程执行完毕,当前线程是:"+Thread.currentThread().getId()+"剩余控制器还有:"+countDownLatch.getCount());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class CounDownLatchTest2 {
public static void main(String[] args) throws InterruptedException {
//模拟瞬时高并发.
CountDownLatch latch = new CountDownLatch(1);
for (int i = 0; i < 300; i++) {
Thread thread = new Thread(new MyThread(latch));
thread.start();
}
System.out.println("准备放线程!!!");
for (int i = 3; i > 0; i--) {
Thread.sleep(1000);
System.out.println(i);
}
System.out.println("冲鸭!");
latch.countDown();
}
static class MyThread implements Runnable {
private CountDownLatch countDownLatch;
public MyThread(CountDownLatch latch) {
this.countDownLatch = latch;
}
@Override
public void run() {
try {
// waiting the ? door open.
countDownLatch.await();
// starting do something!!!!!!
System.out.println("冲鸭!!!! 干他呀的!" + "我是线程编号:" + Thread.currentThread().getId() + "我要打" + Thread.currentThread().getId() + "个!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class CyclicBarrierTest {
public static void main(String[] args) {
//模拟瞬时高并发.
Integer threadNum = 5;
CyclicBarrier latch = new CyclicBarrier(threadNum);
for (int i = 0; i < threadNum; i++) {
Thread thread = new Thread(new MyThread(latch));
thread.start();
}
System.out.println("success");
}
static class MyThread implements Runnable {
private CyclicBarrier cyclicBarrier;
public MyThread(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
System.out.println("I'm ready! i'm thread: " + Thread.currentThread().getId());
System.out.println("on waiting other brothers num: " + (cyclicBarrier.getNumberWaiting() + 1));
cyclicBarrier.await();
System.out.println("all rights, let's fighting!!!");
} catch (Exception e) {
}
}
}
}