目录
方式1:使用synchronized+wait/notify实现
这是个老生常谈的问题了,但里面涵盖的知识还是有必要好好琢磨一下子。这里简单总结了一下,写了个多个线程交替打印1-100的例子,实现如下;
方式1:使用synchronized+wait/notify实现
@Slf4j
public class ThreadDemo3 {
public static void main(String[] args) {
RunnableImpl runnable = new RunnableImpl(100,1);
String [] threadNames = new String[]{"A","B","C","D"};
List<Thread> threadList = new ArrayList<Thread>();
for (int i = 0; i < threadNames.length; i++) {
threadList.add(new Thread(runnable,threadNames[i]));
}
runnable.setThreadList(threadList);
for (int i = 0; i < threadList.size(); i++) {
threadList.get(i).start();
}
}
private static class RunnableImpl implements Runnable{
private int count;
private int index;
private List<Thread> threadList;
private Object lock = new Object();
public RunnableImpl(int count ,int index){
this.index = index;
this.count = count;
}
private void setThreadList(List<Thread> threadList){
this.threadList = threadList;
}
@Override
public void run() {
while(index < count){
synchronized (lock){
if(Thread.currentThread().getName().equals("A") ){
while(index % 4 != 1){
try {
lock.wait();
} catch (InterruptedException e) {
break;
}
}
}else if(Thread.currentThread().getName().equals("B") ){
while(index % 4 != 2){
try {
lock.wait();
} catch (InterruptedException e) {
break;
}
}
}else if(Thread.currentThread().getName().equals("C") ){
while(index % 4 != 3){
try {
lock.wait();
} catch (InterruptedException e) {
break;
}
}
}else if(Thread.currentThread().getName().equals("D") ){
while(index % 4 != 0){
try {
lock.wait();
} catch (InterruptedException e) {
break;
}
}
}
if(index > count){
this.interrupt();
break;
}
log.info("{} ---->{}",Thread.currentThread().getName(),index);
index++;
lock.notifyAll();
}
}
}
private void interrupt() {
for (int i = 0; i < threadList.size(); i++) {
threadList.get(i).interrupt();
}
}
}
}
方式2:使用 Lock+Condition实现
@Slf4j
public class ThreadDemo4 {
public static void main(String[] args) {
Runnable runnable = new RunnableImpl(100,1);
String [] threadNames = new String[]{"A","B","C"};
List<Thread> threadList = new ArrayList<Thread>();
for (int i = 0; i < threadNames.length; i++) {
threadList.add(new Thread(runnable,threadNames[i]));
}
for (int i = 0; i < threadList.size(); i++) {
threadList.get(i).start();
}
}
private static class RunnableImpl implements Runnable{
private int count;
private int index;
private Lock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
public RunnableImpl(int count ,int index){
this.index = index;
this.count = count;
}
@Override
public void run() {
while(index < count){
lock.lock();
try{
if(Thread.currentThread().getName().equals("A") ){
while(index % 3 != 1 ){
conditionA.await();
}
conditionB.signal();
}else if(Thread.currentThread().getName().equals("B") ){
while(index % 3 != 2 ){
conditionB.await();
}
conditionC.signal();
}else if(Thread.currentThread().getName().equals("C") ){
while(index % 3 != 0 ){
conditionC.await();
}
conditionA.signal();
}
if(index > count){
break;
}
log.info("{} ---->>{}",Thread.currentThread().getName(),index);
index++;
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
}
}
方式3:通过 LockSupport实现
@Slf4j
public class ThreadDemo5 {
public static void main(String[] args) {
String threadNames[] = new String[]{"A","B","C"};
int index = 1;
int count = 100;
List<Thread> threadList = new ArrayList<Thread>();
RunnableImpl runnable = new RunnableImpl(index,count,threadList);
for (int i = 0; i < threadNames.length; i++) {
threadList.add(new Thread(runnable,threadNames[i]));
}
for (int i = 0; i < threadList.size(); i++) {
threadList.get(i).start();
}
}
private static class RunnableImpl implements Runnable{
private int index;
private int count;
private List<Thread> threads;
public RunnableImpl(int index, int count,List<Thread> threads){
this.index = index;
this.count = count;
this.threads = threads;
}
@Override
public void run() {
while(index <= count){
String threadName = Thread.currentThread().getName();
if(threadName.equals("A")){
if((index % (threads.size())) !=1){
LockSupport.park();
}else{
log.info(Thread.currentThread().getName()+" --->"+index);
index++;
LockSupport.unpark(threads.get(1));
}
}else if(threadName.equals("B")){
if((index % (threads.size() )) != 2){
LockSupport.park();
}else{
log.info(Thread.currentThread().getName()+" --->"+index);
index++;
LockSupport.unpark(threads.get(2));
}
}else if(threadName.equals("C")){
if((index % (threads.size() ) )!=0){
LockSupport.park();
}else{
log.info(Thread.currentThread().getName()+" --->"+index);
index++;
LockSupport.unpark(threads.get(0));
}
}
if(index>count){
LockSupport.unpark(threads.get(0));
LockSupport.unpark(threads.get(1));
LockSupport.unpark(threads.get(2));
}
}
}
}
}
方式4:线程池+LockSupport
@Slf4j
public class ThreadDemo8 {
public static void main(String[] args) throws InterruptedException {
String[] threadNames = new String[]{"A", "B", "C"};
ThreadFactoryImpl threadFactory = new ThreadFactoryImpl(threadNames, threadNames.length);
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 3,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
int[] integer = {1};
while(integer[0] <100){
poolExecutor.execute(() -> {
if(integer[0] >100){
LockSupport.unpark(threadFactory.getThread("A"));
LockSupport.unpark(threadFactory.getThread("B"));
LockSupport.unpark(threadFactory.getThread("C"));
return;
}
if (Thread.currentThread().getName().equals("A")) {
if (integer[0] % 3 != 1) {
LockSupport.park();
} else {
log.info("{} --->> {}", Thread.currentThread().getName(), integer[0]);
integer[0]++;
LockSupport.unpark(threadFactory.getThread("B"));
}
} else if (Thread.currentThread().getName().equals("B")) {
if (integer[0] % 3 != 2) {
LockSupport.park();
} else {
log.info("{} --->> {}", Thread.currentThread().getName(), integer[0]);
integer[0]++;
LockSupport.unpark(threadFactory.getThread("C"));
}
} else if (Thread.currentThread().getName().equals("C")) {
if (integer[0] % 3 != 0) {
LockSupport.park();
} else {
log.info("{} --->> {}", Thread.currentThread().getName(), integer[0]);
integer[0]++;
LockSupport.unpark(threadFactory.getThread("A"));
}
}
});
}
poolExecutor.shutdown();
}
private static class ThreadFactoryImpl implements ThreadFactory {
private int index;
private String[] threadNames;
private Thread[] threads;
public ThreadFactoryImpl(String[] threadNames, int index) {
this.threadNames = threadNames;
threads = new Thread[threadNames.length];
}
public Thread getThread(String threadName) {
for (int i = 0; i < threads.length; i++) {
if (threads[i].getName().equals(threadName)) {
return threads[i];
}
}
return null;
}
@Override
public Thread newThread(Runnable r) {
if (index < threadNames.length) {
threads[index] = new Thread(r, threadNames[index]);
}
return threads[index++ % threadNames.length];
}
}
}
总结
实力源于基础,Java高并发的任务分片依赖于多线程,对于这个知识点还需深入理解一下。我这里简单改写了一下方式1的写法,也可以了解一下,代码中有写的不到位的地方请在留言中指出;
@Slf4j
public class ThreadDemo6 {
public static void main(String[] args) {
String[] threadNames = new String[]{"A","B","C","D","E","F","G","H"};
List<Thread> threadList = new ArrayList<>();
RunnableImpl runnable = new RunnableImpl(100,1,threadNames);
for (int i = 0; i < threadNames.length; i++) {
Thread thread =new Thread(runnable,threadNames[i]);
threadList.add(thread);
}
runnable.setThreadList(threadList);
for (int i = 0; i < threadList.size(); i++) {
threadList.get(i).start();
}
}
private static class RunnableImpl implements Runnable{
private int count;
private int index;
private String[] threadNames;
private Object lock = new Object();
private List<Thread> threadList;
public RunnableImpl(int count ,int index,String[] threadNames){
this.index = index;
this.count = count;
this.threadNames = threadNames;
}
public void setThreadList(List<Thread> threadList){
this.threadList = threadList;
}
@Override
public void run() {
while(index < count){
synchronized (lock){
String name = Thread.currentThread().getName();
for (int i = 0; i < threadNames.length; i++) {
if(name.equals(threadNames[i]) ){
while(index % threadNames.length != (i+1) % threadNames.length ){
try {
lock.wait();
} catch (InterruptedException e) {
break;
}
}
}
}
if(index > count){
this.interrupt();
break;
}
log.info("{} ---->> {}",name ,index);
index++;
lock.notifyAll();
}
}
}
public void interrupt(){
for (int i = 0; i < threadList.size(); i++) {
threadList.get(i).interrupt();
}
}
}
}