线程依次交替执行解决办法

在面试题中,我们经常会遇到这样的题目,线程依次交替执行,比如有三个线程,第一个线程打印1-2-3,第二个线程接着打印4-5-6,第三个线程打印7-8-9,再更换到线程一运行打印10-11-12,依此类推。或者只有两个线程,他们直接交替执行。

我们知道,默认情况下,多线程运行,资源是共享的,也就是说他们是竞争关系,谁得到cpu资源,谁就运行,其他线程等待,当运行完毕,接下来由谁运行,是不确定的,有可能还是刚才抢占过cpu资源的线程执行。

按照一些面试题的要求,我们需要资源按顺序分配,或者公平分配,而不是去争抢。如果是两个线程,可以考虑使用公平锁,这个很好解决,看代码:

package com.xxx.lock;
import java.util.concurrent.locks.ReentrantLock;
public class FairLockDemo {

	public static void main(String[] args) {
		Runnable target = new Runnable(){
			private ReentrantLock lock = new ReentrantLock(true);
			@Override
			public void run() {
				int i=10;
				while (i>0) {
					try{
						lock.lock();
						System.out.println(Thread.currentThread().getName()+"get lock.for loop "+i);
					}finally{
						lock.unlock();
					}
					i--;
				}
			}		
		};
		
		Thread t1 = new Thread(target, "thread-1");
		Thread t2 = new Thread(target, "thread-2");
		t1.start();
		t2.start();
	}

}

运行结果:

thread-1 get lock.for loop 10
thread-2 get lock.for loop 10
thread-1 get lock.for loop 9
thread-2 get lock.for loop 9
thread-1 get lock.for loop 8
thread-2 get lock.for loop 8
thread-1 get lock.for loop 7
thread-2 get lock.for loop 7
thread-1 get lock.for loop 6
thread-2 get lock.for loop 6
thread-1 get lock.for loop 5
thread-2 get lock.for loop 5
thread-1 get lock.for loop 4
thread-2 get lock.for loop 4
thread-1 get lock.for loop 3
thread-2 get lock.for loop 3
thread-1 get lock.for loop 2
thread-2 get lock.for loop 2
thread-1 get lock.for loop 1
thread-2 get lock.for loop 1

代码中用到的公平锁是通过类ReentrantLock来构建的,他默认可以不带参数,如果带了参数true,那么就是一个公平锁。我们看这个类的描述信息:

如果有三个或者三个以上的线程需要依次执行,那么这个公平锁就不合适了,他的效果比没有使用公平锁会好一点,就是任何线程不会一直抢占执行,但是无法保证线程依次按顺序执行。

这里需要用到锁的Condition机制,利用Condition能够帮助我们完成三个或者三个以上的线程依次顺序执行,看代码:下面是一个主线程和两个子线程,他们分别按照顺序执行:

package com.xxx.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionTest {

	public static void main(String[] args) {
		new ConditionTest().init();
	}
	
	public void init(){
		final Business bus = new Business();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i=0;i<10;i++){
					bus.sub2(i);
				}
			}
		}).start();
		
        new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i=0;i<10;i++){
					bus.sub3(i);
				}
			}
		}).start();
        
        for(int i=0;i<10;i++){
        	bus.sub1(i);
        }
	}
}
class Business{
	private int flag = 1;
	Lock lock = new ReentrantLock();
	Condition c1 = lock.newCondition();
	Condition c2 = lock.newCondition();
	Condition c3 = lock.newCondition();
	
	public void sub1(int n){
		lock.lock();
		try{
			while(flag!=1){
				try {
					c1.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			for(int i=0;i<3;i++){
				System.out.println("sub1 thread sequence of " +i+",loop of "+n);
			}
			flag = 2;
			c2.signal();
		}finally{
			lock.unlock();
		}
	}
	public void sub2(int n){
		lock.lock();
		try{
			while(flag!=2){
				try {
					c2.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			for(int i=0;i<3;i++){
				System.out.println("sub2 thread sequence of " +i+",loop of "+n);
			}
			flag = 3;
			c3.signal();
		}finally{
			lock.unlock();
		}
	}
	
	public void sub3(int n){
		lock.lock();
		try{
			while(flag!=3){
				try {
					c3.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			for(int i=0;i<3;i++){
				System.out.println("sub3 thread sequence of " +i+",loop of "+n);
			}
			flag = 1;
			c1.signal();
		}finally{
			lock.unlock();
		}
	}
}

程序运行打印结果:

sub1 thread sequence of 0,loop of 0
sub1 thread sequence of 1,loop of 0
sub1 thread sequence of 2,loop of 0
sub2 thread sequence of 0,loop of 0
sub2 thread sequence of 1,loop of 0
sub2 thread sequence of 2,loop of 0
sub3 thread sequence of 0,loop of 0
sub3 thread sequence of 1,loop of 0
sub3 thread sequence of 2,loop of 0
sub1 thread sequence of 0,loop of 1
sub1 thread sequence of 1,loop of 1
sub1 thread sequence of 2,loop of 1
sub2 thread sequence of 0,loop of 1
sub2 thread sequence of 1,loop of 1
sub2 thread sequence of 2,loop of 1
sub3 thread sequence of 0,loop of 1
sub3 thread sequence of 1,loop of 1
sub3 thread sequence of 2,loop of 1
sub1 thread sequence of 0,loop of 2
sub1 thread sequence of 1,loop of 2
sub1 thread sequence of 2,loop of 2
sub2 thread sequence of 0,loop of 2
sub2 thread sequence of 1,loop of 2
sub2 thread sequence of 2,loop of 2
sub3 thread sequence of 0,loop of 2
sub3 thread sequence of 1,loop of 2
sub3 thread sequence of 2,loop of 2
sub1 thread sequence of 0,loop of 3
sub1 thread sequence of 1,loop of 3
sub1 thread sequence of 2,loop of 3
sub2 thread sequence of 0,loop of 3
sub2 thread sequence of 1,loop of 3
sub2 thread sequence of 2,loop of 3
sub3 thread sequence of 0,loop of 3
sub3 thread sequence of 1,loop of 3
sub3 thread sequence of 2,loop of 3
sub1 thread sequence of 0,loop of 4
sub1 thread sequence of 1,loop of 4
sub1 thread sequence of 2,loop of 4
sub2 thread sequence of 0,loop of 4
sub2 thread sequence of 1,loop of 4
sub2 thread sequence of 2,loop of 4
sub3 thread sequence of 0,loop of 4
sub3 thread sequence of 1,loop of 4
sub3 thread sequence of 2,loop of 4
sub1 thread sequence of 0,loop of 5
sub1 thread sequence of 1,loop of 5
sub1 thread sequence of 2,loop of 5
sub2 thread sequence of 0,loop of 5
sub2 thread sequence of 1,loop of 5
sub2 thread sequence of 2,loop of 5
sub3 thread sequence of 0,loop of 5
sub3 thread sequence of 1,loop of 5
sub3 thread sequence of 2,loop of 5
sub1 thread sequence of 0,loop of 6
sub1 thread sequence of 1,loop of 6
sub1 thread sequence of 2,loop of 6
sub2 thread sequence of 0,loop of 6
sub2 thread sequence of 1,loop of 6
sub2 thread sequence of 2,loop of 6
sub3 thread sequence of 0,loop of 6
sub3 thread sequence of 1,loop of 6
sub3 thread sequence of 2,loop of 6
sub1 thread sequence of 0,loop of 7
sub1 thread sequence of 1,loop of 7
sub1 thread sequence of 2,loop of 7
sub2 thread sequence of 0,loop of 7
sub2 thread sequence of 1,loop of 7
sub2 thread sequence of 2,loop of 7
sub3 thread sequence of 0,loop of 7
sub3 thread sequence of 1,loop of 7
sub3 thread sequence of 2,loop of 7
sub1 thread sequence of 0,loop of 8
sub1 thread sequence of 1,loop of 8
sub1 thread sequence of 2,loop of 8
sub2 thread sequence of 0,loop of 8
sub2 thread sequence of 1,loop of 8
sub2 thread sequence of 2,loop of 8
sub3 thread sequence of 0,loop of 8
sub3 thread sequence of 1,loop of 8
sub3 thread sequence of 2,loop of 8
sub1 thread sequence of 0,loop of 9
sub1 thread sequence of 1,loop of 9
sub1 thread sequence of 2,loop of 9
sub2 thread sequence of 0,loop of 9
sub2 thread sequence of 1,loop of 9
sub2 thread sequence of 2,loop of 9
sub3 thread sequence of 0,loop of 9
sub3 thread sequence of 1,loop of 9
sub3 thread sequence of 2,loop of 9

 通过利用Condition条件,我们构建了三个条件,他们是指三个程序运行的条件,分别是c1,c2,c3,默认他们没有任何区别,无法区分属于哪个线程的条件,我们需要让他们配合一个变量flag使用,当flag=1的时候主线程main线程可以执行,当flag=2时子线程1可以执行,当flag=3的时候,子线程2可以执行,每个线程执行的时候,需要先获取锁,如果满足条件则执行,不满足条件则等待时机,运行完毕需要释放锁资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffy5459

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值