Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java上的多线程和锁_Java_Multithreading_Locking - Fatal编程技术网

Java上的多线程和锁

Java上的多线程和锁,java,multithreading,locking,Java,Multithreading,Locking,我有3个不同的进程轮流随机执行它们的代码 过程1:制作一封信 过程2:产生一个数字 过程3:使用生成的最后一个字符 我需要能够看到字符串是如何被这些进程操纵的,我尝试了多线程处理,但我只能看到字符串每三圈更新一次 如果另一个线程已经在运行,如何锁定每个线程使其无法运行 这是我的主要方法 public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public v

我有3个不同的进程轮流随机执行它们的代码

过程1:制作一封信

过程2:产生一个数字

过程3:使用生成的最后一个字符

我需要能够看到字符串是如何被这些进程操纵的,我尝试了多线程处理,但我只能看到字符串每三圈更新一次

如果另一个线程已经在运行,如何锁定每个线程使其无法运行

这是我的主要方法

    public static void main(String[] args) {

    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {   
                ventanaPrincipal frame = new ventanaPrincipal();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}
建造师

public ventanaPrincipal() {

    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    textField = new JTextField();
    textField.setEditable(false);
    textField.setBounds(10, 88, 414, 20);
    contentPane.add(textField);
    textField.setColumns(10);

    lblNewLabel.setBounds(10, 119, 106, 14);
    contentPane.add(lblNewLabel);

    hilo1 = new Thread(this);
    hilo2 = new Thread(this);
    hilo3 = new Thread(this);
    hilo1.start();
    hilo2.start();
    hilo3.start();
}
运行方法

public void run() {
    while (bandera3 == 0) { 
    Thread ct = Thread.currentThread();
    try {
        Thread.sleep(1000);
    } catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
    }   
    if(ct == hilo1 && bandera1 < 20){
            lblNewLabel.setText("Turno: " + turno);
            cadena = cadena.concat("" + productorLetras());//produce letter
            textField.setText(cadena);
            turno++;
        }
    if(ct == hilo2 && bandera2 < 20) {
            lblNewLabel.setText("Turno: " + turno); 
            cadena = cadena.concat("" + productorNumeros());//produce number
            textField.setText(cadena);
            turno++;
        }
    if(ct == hilo3 && cadena.length() > 0){
            lblNewLabel.setText("Turno: " + turno);
            consumidor();//consume
            textField.setText(cadena);
            turno++;
            }
        if(bandera1 >= 20 && bandera2 >= 20 && cadena.length() == 0){
            bandera3 = 1;
        }
    }
}

我想说的是,问题是,这些变化做得太快,以至于看不见。您直接在每个线程之后启动所有3个线程,并且所有线程都具有相同的超时时间(1000毫秒)。请尝试将等待时间更改为随机值,例如:

Thread.sleep(1000 * Math.random());
但您仍然有一个问题,即您的代码不是多线程保存的。您需要某种同步机制来避免竞争条件


另外,可能还有一点提示:我会为每个线程创建一个新的Runnable,而不是将其与switch/几个if语句一起重用。它使您的代码更易于阅读。

我不确定您对这些if语句做了什么,但我会使用不同的可运行实现,可能是一个内联类,如:

hilo1 = new Thread(new Runnable(){
//Override Runnable
}
您应该在由多个线程使用的字段上使用synchronizedor synchronized blocks语句,如:

synchronized(turno){
       // do stuff with turno that are critical 
}
这里有一个很好的链接:


和Object.wait和Object.notify对于您想要使用的情况来说可能是很好的关键字,但是已经没有了。

您可以尝试将您的运行方法更改为类似以下内容,这将使UI更改与事件线程同步:

while (bandera3 == 0) { 
   final Thread ct = Thread.currentThread();
   try {
       Thread.sleep(1000);
   } catch(InterruptedException ex) {
       Thread.currentThread().interrupt();
   } 
   EventQueue.invokeAndWait( new Runnable() {
       public void run() {
           // your if statements go here.
       }
   });
}
尽管所有这些看起来都有些粗略。例如,我建议为每种类型的操作创建一个单独的可运行类,而不要基于当前线程与字段的等价性来执行条件