- 方法一:synchronized + wait + notify
/**Object 和 this都可以对同步代码块加锁,但是this锁的是类的实例,如果该实例被他人拿走, 则本线程永远拿不到锁。Object也可以通过反射获取,但相比于this多一层保护。 为什么final?因为防止LOCK被重新赋值,相当于被其他线程抢走锁。*/ private static final Object LOCK = new Object(); private void printABC(int targetNum){ while(num <= 100){ synchronized(LOCK){ /*用if会造成假唤醒的问题,如果if,执行了wait之后,被唤醒了就不会再判断if条件。 while被唤醒之后会先执行while内的判断条件,避免在wait期间判断条件发生变化。*/ while(num % 3 != targetNum){ try { LOCK.wait(); } catch (Exception e) { e.printStackTrace(); } } for (int i = 0; i < 5; i++) { num++; if(num > 100){ break; } System.out.println(Thread.currentThread().getName() + "-->" + String.valueOf(num)); } LOCK.notifyAll(); } } }
public static void main(String[] args) { WaitNotifyABC waitNotifyABC = new WaitNotifyABC(); new Thread(() -> { waitNotifyABC.printABC(0); },"线程A").start(); new Thread(() ->{ waitNotifyABC.printABC(2); },"线程B").start(); new Thread(() -> { waitNotifyABC.printABC(1); },"线程C").start(); } }
- 方法二:Lock
Lock方法和synchronized方法相似,对同步代码块加锁,无论哪个线程拿到锁之后都需要满足num%3 == targetNum才能执行。
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockABC { private volatile int num = 0; private Lock lock = new ReentrantLock(); private void printABC(int targetNum){ while(num <= 100){ lock.lock(); if(num % 3 == targetNum){ for (int i = 0; i < 5; i++) { num++; if(num > 100){ break; } System.out.println(Thread.currentThread().getName() + "-->" + String.valueOf(num)); } } lock.unlock(); } } public static void main(String[] args) { LockABC lockABC = new LockABC(); new Thread(() -> { lockABC.printABC(0); },"线程A").start(); new Thread(() -> { lockABC.printABC(2); },"线程B").start(); new Thread(() -> { lockABC.printABC(1); },"线程C").start(); } }
- 方法三:Lock+Condition
import java.net.CacheRequest; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockCondition { private volatile int num = 0; private Lock lock = new ReentrantLock(); private Condition ca = lock.newCondition(); private Condition cb = lock.newCondition(); private Condition cc = lock.newCondition(); private void printABC(int targetNum, Condition currentThread, Condition nextThread){ while(num <= 100){ lock.lock(); try { while(num % 3 != targetNum){ if(num > 100){ break; } currentThread.await(); } for (int i = 0; i < 5; i++) { num++; if(num > 100){ break; } System.out.println(Thread.currentThread().getName() + "-->" + String.valueOf(num)); } nextThread.signal(); } catch (Exception e) { e.printStackTrace(); } finally{ lock.unlock(); } } } public static void main(String[] args) { LockCondition lockCondition = new LockCondition(); new Thread(() -> { lockCondition.printABC(0, lockCondition.ca, lockCondition.cb); },"线程A").start(); new Thread(() -> { lockCondition.printABC(2, lockCondition.cb, lockCondition.cc); },"线程B").start(); new Thread(() -> { lockCondition.printABC(1, lockCondition.cc, lockCondition.ca); },"线程C").start(); } }
- 方法四:Semophore
import java.util.concurrent.Semaphore; public class SemaphoreABC { private volatile int num = 0; private Semaphore sa = new Semaphore(1); private Semaphore sb = new Semaphore(0); private Semaphore sc = new Semaphore(0); private void printABC(Semaphore currentThread, Semaphore nextThread){ while(num <= 100){ try { currentThread.acquire(); for (int i = 0; i < 5; i++) { num++; if(num > 100){ break; } System.out.println(Thread.currentThread().getName() + "-->" + String.valueOf(num)); } nextThread.release(); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { SemaphoreABC semaphoreABC = new SemaphoreABC(); new Thread(() -> { semaphoreABC.printABC(semaphoreABC.sa, semaphoreABC.sb); },"线程A").start();; new Thread(() -> { semaphoreABC.printABC(semaphoreABC.sb, semaphoreABC.sc); },"线程B").start();; new Thread(() -> { semaphoreABC.printABC(semaphoreABC.sc, semaphoreABC.sa); },"线程C").start();; } }
标签:printABC,Java,Thread,打印,private,num,线程,new From: https://www.cnblogs.com/iscanghai/p/17280261.html