使用Java 8进行线程排序
问题描述:
我有一个简单的程序用于两个线程交替地打印增量数字。使用Java 8进行线程排序
所以, 第一线程打印:1个
第二个线程打印:2个
第一线程打印:3 ...等等
我能使用 '线' 类做这个。但我想看看如何使用Executor类来做到这一点。
用以下代码.... executor类似乎不工作。任何指针?
代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LocksPackagePractice {
private int i = 0;
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Runnable r =() -> {
for(int x = 0; x < 5; x++){
printValue();
}
printValue();
};
public static void main(String[] args) {
new LocksPackagePractice().trigger();
}
void trigger(){
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(r);
}
void printValue(){
lock.lock();
try {
i++;
System.out.println(Thread.currentThread().getName() + " and value is = " + i);
condition.signal();
condition.await();
} catch(InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
答
在制造程序中的一些变化。运行它并检查它是否解决了混淆。
public class LocksPackagePractice {
private int i = 0;
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Runnable r =() -> {
printValue();
};
public static void main(String[] args) {
new LocksPackagePractice().trigger();
}
void trigger() {
ExecutorService service = Executors.newFixedThreadPool(2);
service.submit(r);
for (int i = 0; i < 5; i++) {
service.execute(r);
}
}
void printValue() {
lock.lock();
try {
i++;
System.out.println(Thread.currentThread().getName() + " and value is = " + i);
condition.signal();
condition.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
这会给你下面的输出
pool-1-thread-1 and value is = 1
pool-1-thread-2 and value is = 2
pool-1-thread-1 and value is = 3
pool-1-thread-2 and value is = 4
pool-1-thread-1 and value is = 5
pool-1-thread-2 and value is = 6
答
我不知道,但你需要输入订货?因为你使用阻塞操作(锁),并且在性能方面不好。
此代码:
private AtomicInteger number = new AtomicInteger(0);
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
ForTestApplication testApplication = new ForTestApplication();
for (int i = 0; i < 100; i++) {
executor.execute(testApplication::print);
}
}
public void print() {
System.out.println(Thread.currentThread().getName() + " : " + number.incrementAndGet());
}
使用AtomicInteger
,而不是简单的int
值和锁定操作。但是,输出的顺序可能是这样的:
pool-1-thread-1 : 1
pool-1-thread-2 : 2
pool-1-thread-1 : 3
pool-1-thread-1 : 4
pool-1-thread-2 : 5
pool-1-thread-2 : 7
pool-1-thread-1 : 6
pool-1-thread-2 : 8
pool-1-thread-1 : 9
pool-1-thread-2 : 10
它你需要在你的输出订单,然后需要思考如何处理它。
您至少需要2个runnables(任务),以便执行程序可以使用不同的线程运行它们。此外,你需要一些任务之间的沟通方式(或让他们产生新的子任务),以获得你想要的行为。不过,我强烈建议你深入挖掘线程和任务。让2个线程按顺序运行基本类似的任务会违背多线程的目的 - 就像绑定到特定线程的任务会违反线程池的目的一样。 – Thomas
谢谢托马斯。 如果“有2个线程按顺序运行一个基本类似的任务有违多线程的目的”....那么Executor.newFixedThreadPool()和.execute(runnable)方法的用法是什么? 我们是不是只是通过不同的线程执行相同的runnable? – Deep
'Executor.newFixedThreadPool()'是为了提供一个固定的工作线程池,其中的任何一个都可以交给一个需要执行的任务。通过'Executor.execute(Runnable)',您可以将单个任务传递给执行程序,然后将该任务交给工作线程。基本思想是一个任务由一个线程执行。 – Thomas