快捷搜索:  汽车  科技

多线程同步代码大全(同步多线程集成测试的五种方式)

多线程同步代码大全(同步多线程集成测试的五种方式)最后,我列出了同步多线程集成测试的五种方法; 但是,如果您能想到其他方法,请让我知道..。在列出了所有这些方法之后,接下来要考虑的是哪一种是最好的?在问这个问题的时候,你必须用“最好”来定义“最好”这个词,为了什么?最简单的方法?可维护性?速度还是代码大小?毕竟编程是做出正确决定的艺术。您可能已经猜到,我不喜欢随机延迟的想法,更喜欢使用 CountDownLatch。Join ()有点老派; 请记住,Semaphore 和 CountDownLatch 之类的代码是为了改进原来的 Java 线程技术而编写的。ExecutorService 对于我们这里需要的东西来说似乎有点沉重。归根结底,技巧的选择实际上取决于个人的喜好。public class ThreadWrapper { /** * Start the thread running so that it does some work

几周前,我写了一篇关于同步多线程集成测试的博客,该博客在DZone Javalobby上重新发布,从那里收到了 Robert Saulnier 的评论,他非常正确地指出你也可以使用 join() 来同步工作线程及其单元测试。这让我想到,你可以通过多少种方式来同步多线程集成测试?于是,我开始数...并想出了:

多线程同步代码大全(同步多线程集成测试的五种方式)(1)


使用随机延迟。
添加 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;

}

}

With a Future

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 对于我们这里需要的东西来说似乎有点沉重。归根结底,技巧的选择实际上取决于个人的喜好。

最后,我列出了同步多线程集成测试的五种方法; 但是,如果您能想到其他方法,请让我知道..。

猜您喜欢: