Java 多线程执行顺序
我在理解为什么我多次创建一个实现可运行接口的对象时遇到了一些问题,我在Java 多线程执行顺序,java,multithreading,Java,Multithreading,我在理解为什么我多次创建一个实现可运行接口的对象时遇到了一些问题,我在@Test上创建了它们,当我调用该对象start()时,它首先运行@Test,然后如果对象是可运行的,它就会运行run方法 代码如下: public class Tests extends { @Test(testName = "754") public void concurrenciaGuardarArticuloTMP() throws Exception { try {
@Test
上创建了它们,当我调用该对象start()
时,它首先运行@Test
,然后如果对象是可运行的,它就会运行run方法
代码如下:
public class Tests extends {
@Test(testName = "754")
public void concurrenciaGuardarArticuloTMP() throws Exception {
try {
this.codigoBarras =this.generarCodigoDeBarra();
System.out.println(codigoBarras);
logger.info("Codigo de barras generado fue ::: " + codigoBarras);
GuardarArticuloTMP articulo1 = new GuardarArticuloTMP(GuardarArticuloTMP.TMP.TMP_CODIGO_BARRA,"TMP, Hilo 1", codigoBarras,35);
GuardarArticuloTMP articulo2 = new GuardarArticuloTMP(GuardarArticuloTMP.TMP.TMP_CODIGO_BARRA,"TMP, Hilo 2", codigoBarras,37);
articulo1.start();
articulo2.start();
logger.info("Codigo de barras generado fue ::: " + codigoBarras);
System.out.println("Codigo de barras generado fue ::: " + codigoBarras);
logger.info(writeDTO(articulo1.getArticulo()));
} catch (Exception ex) {
logger.error("Error guardando Articulo.", ex);
this.setExecutionDetail(ex.getMessage());
}
}
}
和Guardarticulos类别:
public class GuardarArticuloTMP extends Setup implements Runnable{
private Thread t;
private String threadName;
private String codigoBarras;
private int numeroCaja;
private static Logger logger = Logger.getLogger(GuardarArticulo.class);
/**
* @param pThreadName nombre del hilo
* @param pCodigoBarras codigo de barras
* @param pNumeroCja numero de caja para el local
*/
public GuardarArticuloTMP(TMP tmp, String pThreadName, String pCodigoBarras, int pNumeroCja) {
this.threadName = pThreadName;
this.codigoBarras = pCodigoBarras;
this.numeroCaja = pNumeroCja;
this.tmp = tmp;
initLogger();
}
/**
* Crea un articulo
* @return nos devuelve un articulo
* @throws Exception
*/
private ArticuloFacadeDTO crearArticulo() throws Exception {
//creates Articulo
return toSave;
}
@Override
public void run() {
System.out.println("Corriendo " + this.threadName.toUpperCase() + " !!!!!!!!!!!!!!!!!!!!!!!!");
logger.info("Corriendo " + this.threadName.toUpperCase() + " !!!!!!!!!!!!!!!!!!!!!!!!");
try{
Thread.sleep(50);
logger.info("estoy en el run por crear el articulo");
ArticuloFacadeDTO toSave = crearArticulo();
writeDTO(toSave);
mgr.guardarArticuloFacade(toSave);
Thread.sleep(50);
}catch(Exception ex) {
ex.printStackTrace();
logger.error("Error::: ",ex);
}
}
public void start()
{
logger.info("Empezado el thread " + this.threadName);
if (t == null) {
t = new Thread (this, threadName);
t.setPriority(10);
t.start();
}
}
}
我期望的是,在调用所有的
start()
之后,它在线程上启动,然后完成@Test
方法的运行,因此我会进行所需的验证。如果使用Runnable
接口,Java多线程中没有执行顺序。不能保证articulo1
将在articulo2
之前完成
@Test
的问题是:它在一个单独的线程上运行,因此测试方法在Runnable
s完成之前就完成了
我建议您确实应该仔细阅读Oracle网页上的官方线索。我不确定是否理解您的问题,但除非使用某种标志,否则您无法确保线程之间的特定顺序 这可能不是最好的解决方案,但如果将其应用于一个小项目,它可以为您服务 例如,您可以使用全局/静态变量或可用的构造(如
join或countdownlachts
)来实现这一点
希望对你有帮助!:) 您没有描述您遇到的实际问题,也没有包括start()方法的实现。对不起,我不能真正理解问题是什么。在我看来,您可能对java中多线程的工作方式有一些误解。你能详细说明一下吗?你说的是你的期望,但你没有说程序实际做了什么。线程启动了吗?调用
Thread.start()
将创建一个新的执行堆栈,并返回主线程,继续执行main
中的下一步。它不会等待生成的线程run()
完成。如果您想协调访问,那么您需要使用任何构造,如join()、wait/notify、countdownlatch或semaphoes
No在启动后,您应该在main()中调用t1.join(),以便main将等待t1的run()完成。您认为使用静态变量可以准确地排序执行吗?你能解释一下吗?静态变量叫做“A”。每次创建新线程时,他都会递增一个名为“B”的变量,并将该变量值作为参数传递给新线程。如果线程中的B值等于静态变量A,那么是时候运行它了,最后它将增加静态变量。如果它不相等,那么线程将等待变量A等于B。如果我完全错了,请纠正我!:)您的想法很好,但当您实际实现它时,您会发现静态并不是一个好的选择,您需要同步对静态变量的访问,以使其按照您的期望工作,但它存在线程争用的问题。此外,您需要确保始终读取更新的静态变量,需要运行循环检查变量更新并对其执行操作。这有点复杂,但是如果你正确地使用volatile
和atomics
,你也许可以做到:)但是你不需要重新发明轮子,您可以只使用现有的结构,如join或CountDownLatchs
进行向下投票的原因可能是您的答案没有解决OP的问题,因为您没有正确解释它。你需要提供一个好的解决方案,或者至少指导他正确的方向:)编辑你的答案以反映这一点哦,我明白了。我不知道那些构造,现在我知道了。非常感谢@Arkantos!:)