Dúvida Multithreading (simples)

1 resposta
Erick_Ribeiro

Olá. Gostaria de saber como faço para apresentar um conjunto de números (não ordenados) usando 2 Threads.

Por exemplo, se eu quiser apresentar os números de 0 a 10 usando duas Threads.

A parte principal do meu código é:

botao2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				count = 0;
				
				Thread threadOne = new Thread() {
					@Override
					public void run() {

						//essa thread deve executar de 0 até 5
						while (count <= finish/2) {
							System.out.println(count);
							count++;
						}
					}
				};
				Thread threadTwo = new Thread() {
					@Override
					public void run() {
						//essa thread deve executar de 6 até 10
						while (count + finish <= finish) {
							System.out.println(count);
							count++;
						}
					}
				};
				threadOne.start();
				threadTwo.start();
			}
		});

Meu código completo é:

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ThreadBenchmark extends JFrame {
	private int count, finish;
	private JPanel painel = new JPanel();
	private JButton botao1 = new JButton("1 Thread");
	private JButton botao2 = new JButton("2 Threads");
	private JButton botao4 = new JButton("4 Threads");

	public ThreadBenchmark() {
		count = 0;
		finish = 10;
		painel.add(botao1);
		painel.add(botao2);
		painel.add(botao4);
		getContentPane().add(painel);

		botao1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				count = 0;
				
				Thread threadOne = new Thread() {
					@Override
					public void run() {
						while (count <= finish) {
							System.out.println(count);
							count++;
						}
					}
				};
				threadOne.start();
			}
		});
		
		botao2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				count = 0;
				
				Thread threadOne = new Thread() {
					@Override
					public void run() {
						//essa thread executa de 0 até 5
						while (count <= finish/2) {
							System.out.println(count);
							count++;
						}
					}
				};
				Thread threadTwo = new Thread() {
					@Override
					public void run() {
						//essa thread deve executar de 6 até 10
						while (count + finish/2 <= finish) {
							System.out.println(count);
							count++;
						}
					}
				};
				threadOne.start();
				threadTwo.start();
			}
		});
		
		botao4.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				count = 0;
				
				Thread threadOne = new Thread() {
					@Override
					public void run() {
						while (count <= finish) {
							System.out.println(count);
							count++;
						}
					}
				};
				threadOne.start();
			}
		});
	}

	public static void main(String[] args) {
		ThreadBenchmark tb = new ThreadBenchmark();
		tb.setTitle("Threading com Swing");
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		tb.setLocation((screenSize.width - 480) / 2,
				(screenSize.height - 320) / 2);
		tb.setSize(480, 320);
		tb.setVisible(true);
		tb.setDefaultCloseOperation(EXIT_ON_CLOSE);

	}

}

Obrigado desde já!


Erick

1 Resposta

ViniGodoy

Eu começaria criando o Runnable que representa a task a ser executada:

public class CountTask implements Runnable {
    private int from;
    private int to;

    public CountTask(int from, int to) {
         this.from = from;
         this.to = to;
    }

    @Override
    public void run() {
         for (int i = from; i <= to; i++) {
              System.out.println(i);
         }
    }
}

Depois seu actionListener se reduziria para:

botao2.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        Thread one = new Thread(new CountTask(1, finish/2));
        Thread two = new Thread(new CountTask(finish/2+1, finish));
        one.start();
        two.start();
    }
});

Observe que o Runnable guarda cópia dos valores de from e to em suas próprias variáveis e tem seu próprio valor de i.
Não é uma boa prática compartilhar variáveis quando estiver usando threads, a menos que as sincronize.

Em seu caso, isso é especialmente relevante para a variável count. Ela não deveria ser compartilhada entre as threads nem mesmo se fosse sincronizada.

Criado 7 de setembro de 2014
Ultima resposta 7 de set. de 2014
Respostas 1
Participantes 2