多线程同步代码大全(同步多线程集成测试的五种方式)
多线程同步代码大全(同步多线程集成测试的五种方式)最后,我列出了同步多线程集成测试的五种方法; 但是,如果您能想到其他方法,请让我知道..。在列出了所有这些方法之后,接下来要考虑的是哪一种是最好的?在问这个问题的时候,你必须用“最好”来定义“最好”这个词,为了什么?最简单的方法?可维护性?速度还是代码大小?毕竟编程是做出正确决定的艺术。您可能已经猜到,我不喜欢随机延迟的想法,更喜欢使用 CountDownLatch。Join ()有点老派; 请记住,Semaphore 和 CountDownLatch 之类的代码是为了改进原来的 Java 线程技术而编写的。ExecutorService 对于我们这里需要的东西来说似乎有点沉重。归根结底,技巧的选择实际上取决于个人的喜好。public class ThreadWrapper { /** * Start the thread running so that it does some work
几周前,我写了一篇关于同步多线程集成测试的博客,该博客在DZone Javalobby上重新发布,从那里收到了 Robert Saulnier 的评论,他非常正确地指出你也可以使用 join() 来同步工作线程及其单元测试。这让我想到,你可以通过多少种方式来同步多线程集成测试?于是,我开始数...并想出了:
使用随机延迟。
添加 CountDownLatch
Thread.join()
获取信号量
带有 Future 和 ExecutorService
现在,我不打算详细解释以下所有内容,我会让代码自己说话,只是说所有代码示例都做了大致相同的事情:单元测试创建一个 ThreadWrapper 实例,然后调用它的 doWork() 方法(或在 Future 的情况下为 call() )。然后单元测试的主线程等待工作线程完成,然后断言测试已通过。
对于演示第 1 点和第 2 点的示例代码,请查看我关于同步多线程集成测试的原始博客,但我不推荐第 1 点:使用随机延迟。
public class ThreadWrapper {
private Thread thread;
/**
* Start the thread running so that it does some work.
*/
public void doWork() {
thread = new Thread() {
/**
* Run method adding data to a fictitious database
*/
@Override
public void run() {
System.out.println("Start of the thread");
addDataToDB();
System.out.println("End of the thread method");
}
private void addDataToDB() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
System.out.println("Off and running...");
}
/**
* Synchronization method.
*/
public void join() {
try {
thread.join();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
public class ThreadWrapperTest {
@Test
public void testDoWork() throws InterruptedException {
ThreadWrapper instance = new ThreadWrapper();
instance.doWork();
instance.join();
Boolean result = getResultFromDatabase();
assertTrue(result);
}
/**
* Dummy database method - just return true
*/
private boolean getResultFromDatabase() {
return true;
}
}
获取信号量
public class ThreadWrapper {
/**
* Start the thread running so that it does some work.
*/
public void doWork() {
doWork(null);
}
@VisibleForTesting
void doWork(final semaphore semaphore) {
Thread thread = new Thread() {
/**
* Run method adding data to a fictitious database
*/
@Override
public void run() {
System.out.println("Start of the thread");
addDataToDB();
System.out.println("End of the thread method");
Semaphore.release();
}
private void addDataToDB() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
aquire(semaphore);
thread.start();
System.out.println("Off and running...");
}
private void aquire(Semaphore semaphore) {
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadWrapperTest {
@Test
public void testDoWork() throws InterruptedException {
ThreadWrapper instance = new ThreadWrapper();
Semaphore semaphore = new Semaphore(1);
instance.doWork(semaphore);
semaphore.acquire();
boolean result = getResultFromDatabase();
assertTrue(result);
}
/**
* Dummy database method - just return true
*/
private boolean getResultFromDatabase() {
return true;
}
}
public class ThreadWrapper implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
System.out.println("Start of the thread");
Boolean added = addDataToDB();
System.out.println("End of the thread method");
return added;
}
/**
* Add to the DB and return true if added okay
*/
private Boolean addDataToDB() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Boolean.valueOf(true);
}
}
public class ThreadWrapperTest {
@Test
public void testCall() throws ExecutionException InterruptedException {
ThreadWrapper instance = new ThreadWrapper();
ExecutorService executorService = Executors.newFixedThreadPool(1);
Future<Boolean> future = executorService.submit(instance);
Boolean result = future.get();
assertTrue(result);
}
}
在列出了所有这些方法之后,接下来要考虑的是哪一种是最好的?在问这个问题的时候,你必须用“最好”来定义“最好”这个词,为了什么?最简单的方法?可维护性?速度还是代码大小?毕竟编程是做出正确决定的艺术。您可能已经猜到,我不喜欢随机延迟的想法,更喜欢使用 CountDownLatch。Join ()有点老派; 请记住,Semaphore 和 CountDownLatch 之类的代码是为了改进原来的 Java 线程技术而编写的。ExecutorService 对于我们这里需要的东西来说似乎有点沉重。归根结底,技巧的选择实际上取决于个人的喜好。
最后,我列出了同步多线程集成测试的五种方法; 但是,如果您能想到其他方法,请让我知道..。