NutzCN Logo
问答 一个多线程的问题,请教下
发布于 2580天前 作者 qq_64f81159 2166 次浏览 复制 上一个帖子 下一个帖子
标签:

有种业务场景:提交若干任务,任务的执行是异步的但是必须一个执行完了之后再执行下一个。现在要求,在上一个任务还没执行完之前,后面陆续提交若干任务的话,如果没有未执行的任务,就将该任务加到待执行任务队列中,如果有未执行的任务,就将该任务替换那个未执行的任务。简之就是任务队列中最多只允许2个任务,1个任务正在执行,一个任务待执行,新加任务,会替换待执行的任务,这个能提供下思路吗

14 回复

貌似很简单吧, 新任务进来的时候,直接覆盖next就好了

public class TRunner {
    public Runnable next;
    private Runnable current;

    public void run() {
             while (true) {
                  if (next == null) {
                      Thread.sleep(1);
                      continue;
                  }
                  current = next;
                  next = null;
                  current.run();
             }
     }
}

这个不对吧 。下面这样写没啥意义啊 ,current=next不就是无脑吧队列第二个付给前一个 ,现在的要求是新加任务,会替换待执行的任务,不是无脑替换啊

current = next;
                  next = null;
                  current.run();

next总是保存下一个任务, 由其他线程为它赋值, 这个线程只管拿任务执行

例如 :
A线程产生了任务1, 放入next, 因为TRunner 正在空转, 所以马上将next任务放入current,开始执行
B线程产生了任务2, 放入next, 这时候 current和next都有值, 其中current正在执行, next等待执行
C线程产生了任务3, 放入next, 这时候, next原本是任务2, 待执行, next被覆盖为任务3, TRunner 继续跑current(任务1)
TRunner 跑完current(任务1), 看到next(任务3)有值, 放入current,开始执行(任务3)

能满足 "最多只允许2个任务,1个任务正在执行(current),一个任务待执行(next),新加任务,会替换待执行的任务"

额 这貌似算一种解决思路 不过好像变成单线程了。感觉有点low..

 if (next == null) {
                      Thread.sleep(1);
                      continue;
                  }

这个貌似就有问题吧 ,第一个任务不定什么时候来 ,这个一定会报空指针啊。

哪里空指针了?怎么会空指针?

没有next的时候就会报空指针啊 任务不知道什么时候来啊

public class TaskServer {
	private Runnable current;
	private Runnable next;

	public synchronized void runTask() {
		while(this.next==null){
			try {
				wait();
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		}
		current = next;
		next = null;
		current.run();
		notifyAll();
	}

	public synchronized void setNext(Runnable next){
		while(this.next!=null){
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.next = next;
		notifyAll();
	}
}

我这样改一下不知道合理不 ,兽总指点下

为啥setNext要wait?

主要是为了上面啊 ,这里我必须next有值我才把next复制给current啊 ,不然按照你写的,第二次next没来的,current被赋了空值,不会导致空指针吗,这里就两个方法 没地方写了。不这么写不是会报错嘛。

while(this.next==null){
			try {
				wait();
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		}
  while (true) {
                  if (next == null) {
                      Thread.sleep(1);
                      continue;
                  }
                  current = next;
                  next = null;
                  current.run();
             }

你这里首先赋next 然后run把 如果其他线程没有再次赋next 你这个空转不就报空指针了

有continue啊,不会往下走的

嗯 是的。。,可是感觉和想的不一样,其实开始想的是用queue来做 还要判断线程的状态

所以你写的setNext里面的wait是不对的

添加回复
请先登陆
回到顶部