Pętla dla wielu wątków

0

Zrobiłem tak żeby każda iteracja dostawała swój wątek:

public class AppMain {
	public static void main(String[] args){
		for (int i = 0; i < 10; i++){
			MyThread mt = new MyThread(i);
			mt.start();
		}
	}
}
public class MyThread extends Thread {

	int i;

	public MyThread(int i) {
		this.i = i;
	}

	@Override
	public void run() {
		try {
			Thread.sleep(1000);
			System.out.println(i);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

ale nie wiem jak zrobić by pętla była podzielona tylko między 2 wątki a najlepiej to między n wątków.

0

Rozjaśnij:

  1. Co te wątki mają robić ?
  2. Co to znaczy pętla podzielona na wątki?
  3. Zapewne nie potrzebujesz wątków.
1

Semaphor albo okoń

robisz 10 wątków w tej twojej puli, robisz Semaphora na 2 - i teraz jak wątek nic nie robi zwalnia ticket i inny wątek może pracować - nie wiem po co ci to, ale tak to będzie banglać - przy okazji masz eleganckie memory-relationship, release i acquire mają happends-before

0

Z listy robisz 'parallelStream', na nim 'map' z funkcją mapującą jako parametr i na końcu 'collect' z powrotem do listy.

1

Możesz użyć thread pool jak napisał vpiotr https://www.journaldev.com/1069/threadpoolexecutor-java-thread-pool-example-executorservice
Możesz też stworzyć np BlockingQueue i ładować do niej zadania do wykonania, natomiast inne wątki bedą czytać z tej kolejki i wykonywać zadanie, czyli po prostu schemat 1 producent i wielu konsumentów https://www.journaldev.com/1034/java-blockingqueue-example

1

Korzystając z twojego wyjaśnienia:

Program ma zczytywać ponad 100 stron internetowych. Strony internetowe są zebrane w List i jest przygotowana metoda do tego, więc wystarczy przeiterować po tej List na każdym elemencie odpalajć metodę. Chciałbym to zrobić wątkami, wtedy będzie szybciej, bo strony się długo ładują, nie dlatego, że mam wolny internet tylko stronka tak wolno wysyła, więc jak odpalać będę po 4 naraz to mój internet wyrobi i będzie szybciej, ale jak odpalę 100 wątków naraz to mi internet nie uniesie. - Julian_

Czyli trochę niepotrzebnie bawisz się w wątki.
Odpowiedź @vpiotr jest chyba najwygodniejsza. Będziesz sobie mógł ustalić ile na raz wątków przerabia IO.
parellelStream też da radę, ale ma troszkę niuansów, nie polecam. Nie wysterujesz tak łatwo ile wątków się tym zajmuje.

Korzystając z asynchronicznego klienta możesz kod zredukować do praktycznie jednowątkowego:
https://github.com/AsyncHttpClient/async-http-client,
ale to nie jest rozwiązanie na Newbie.

0

Dzięki czyli będzie tak:

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AppMain {
	public static void main(String[] args){
		
		final int NUMBER_OF_THREADS = 2;
		
		Executor exec = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
		for (int i = 0; i < 10; i++){
			MyThread mt = new MyThread(i);
			exec.execute(mt);
		}
		
	}
}
public class MyThread extends Thread {

	int i;

	public MyThread(int i) {
		this.i = i;
	}

	@Override
	public void run() {
		try {
			Thread.sleep(1000);
			System.out.println(i);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Teraz zastanawiam się jak zrobić, by zachować kolejność wypisywania tej iteracji tzn. żeby wątek 2 czekał ze skończeniem na wątek 1 jeśli nie skończy, ale zaczynał nie czekając.

1

Teraz zastanawiam się jak zrobić, by zachować kolejność wypisywania tej iteracji tzn. żeby wątek 2 czekał ze skończeniem na wątek 1 jeśli nie skończy, ale zaczynał nie czekając.

Opisz to jakoś bardziej :)

Jak chcesz żeby wątek czekał na drugi to najlepiej CyclicBarrier albo CountDownLatch

0

Chodzi o to, że jak wątek 1 i wątek 2 jest odpalany równocześnie (tak jak w tym moim ostatnim poście) to czasem 1 wątek wypisze na ekran wynik pierwszy, a czasem 2. A ja chcę by szło tak o: wątek1 -> wątek2 -> wątek1 -> wątek2 ALE by wątek1 i wątek2 startowały równocześnie tylko kończyły się w takiej kolejności jak podałem. Czyli join() nie pomoże.

0

Ale stream to po prostu buffor więc czego tu nie wiesz?

Hmm co do wątków, to możesz przecież zaczekać aż wszystkie skończą i wyświetlić w odpowiedniej kolejności, takiej jak chcesz.

0

Nie trzeba sortować, bo czekasz aż skończy się pierwszy, a jak drugi się skończył, to funkcja czekająca na drugi skończy się natychmiast itp.

1

Proponowałbym zamiast Thread używać Runnable i submit zamiast execute.

http://tutorials.jenkov.com/java-util-concurrent/executorservice.html

Ew. prościej - zobacz powyżej przykład z invokeAll.

1 użytkowników online, w tym zalogowanych: 0, gości: 1