Söva tråd från annan tråd i Java, utan att märkbart ändra tiden att köra tråden.

Permalänk
Medlem

Söva tråd från annan tråd i Java, utan att märkbart ändra tiden att köra tråden.

Hej hallå!
Läser algoritmer och datastrukturer nu på KTH och programmet jag håller på att göra är ett program som grafiskt jämför sorteringsmetoder(just nu merge, quick och insertion).
I och med att metoderna är väldigt snabba så måste jag då sakta ned dom, och det enklaste och jämnaste skulle vara att kunna sleepa alla från main med något
sorteringar.sleep(100);
eller
quicksort.sleep(100);
men ifall jag endast gör så så kommer main sleepas och inte quicksort metoden (quicksort extendar Thread).

Sätt som jag sett föreslås för att pausa trådar är att lägga in en while(sleep){} som då körs ifall man ändrar variabeln sleep via någon metod
sleep(boolean value){
sleep=value;
}
men grejjen är då att while-loopen tar lite tid att kolla värdet på sleep så jag antar att algoritmerna då ändrar hur optimerade de är.
just nu ser min main ut såhär i stort sätt

int array[] = creatarray.random(length, maxvalue); //Skapar en array med length antal värden och maxvalue som maxvärde quicksort quick = new quicksort (array); //Skapar instanser av quick-, merge-, insertion - sort mergesort merge = new mergesort(array); insertionsort insert = new insertionsort(array); graphicdisplay g = new graphicdisplay(length, maxvalue); g.start(); insertion.start(); quick.start(); merge.start();

Så som det är nu kan jag köra alla trådar och den sorterar dom bra grafiskt, men antingen går det väldigt fort, eller så ändras resultaten inbördes (ex. att merge går i vanliga fall snabbare än quick för en nästan sorterad array, men börjar gå långsammare efter att jag lagt in en sleep i den i början av rekursionen).

TL;DR
Behöver hjälp att sleepa några trådar från main tråden, utan att sakta ned trådarna på nått märkbart sätt.
Har prövat att lägga in while(sleep){ } i koden och anropa tråd.sleep(x) från main.

edit.
Vill någon ha all källkod kan jag lägga upp dom i en .zip. Dock är den mesta koden just nu okommenterad :/

Visa signatur

In the end what separates a man from a slave?
Money? Power? No... A man chooses, a slave obeys.
ASUS Z170M-PLUS || Intel Core i7 6700k @ 4,7GHz || 64GB 2133MHz Corsair RAM || MSI NVIDIA RTX 2070 Gaming Z 8GB || Bifenix Prodigy M || 2x CZ TR150 480GB RAID 0 || BeQuiet DarkRock Pro

Permalänk
Medlem

Om du vill se hur saker ändras vore väl det bästa att ingripa direkt i sorterings-algoritmen för att bara ta ett steg i taget sen rita ut det nya tillståndet för att få något i stil med http://www.sorting-algorithms.com/

Att köra algoritmerna parallelt i olika trådar ser jag inte riktigt poängen med. Ska du ta tid på dem så gör du hellre det i isolation. Vad är det egentligen du vill uppnå med jämföringen?

Visa signatur

"Some poor, phoneless fool is probably sitting next to a waterfall somewhere, totally unaware of how angry and scared he's supposed to be." - Duncan Trussell

Permalänk
Medlem
Skrivet av gibbon_:

Om du vill se hur saker ändras vore väl det bästa att ingripa direkt i sorterings-algoritmen för att bara ta ett steg i taget sen rita ut det nya tillståndet för att få något i stil med http://www.sorting-algorithms.com/

Att köra algoritmerna parallelt i olika trådar ser jag inte riktigt poängen med. Ska du ta tid på dem så gör du hellre det i isolation. Vad är det egentligen du vill uppnå med jämföringen?

Frågade min lärare idag så svarade han typ "äh, ni behöver inte kunna så mycket så bara du får fram ett program som ritar upp dom ungefär lika snabbt som annars så är det lungt" så nu har jag slängt in massa sleep över allt men så att de jämfört med varandra fortfarande går lika snabbt.

Anyhow så känns det utifrån min ursprungsfråga att ifall jag skulle göra det så skulle jag även då behöva göra så trådarna kör extra steg, då ifall jag lägger in efter varje steg i mergesort så blir det fler "steg" per tal den flyttar vilket gör att insertion som är väldigt enkel får en stor fördel.

Andelen till flera trådar var för att jag inte visste annars hur jag skulle göra för att man skulle kunna se arrayerna beräknas parallellt på nått bra sätt. Just nu så är det ett fönster där man ser merge överst, quick i mitten och insertion nederst och de startas exakt samtidigt

Visa signatur

In the end what separates a man from a slave?
Money? Power? No... A man chooses, a slave obeys.
ASUS Z170M-PLUS || Intel Core i7 6700k @ 4,7GHz || 64GB 2133MHz Corsair RAM || MSI NVIDIA RTX 2070 Gaming Z 8GB || Bifenix Prodigy M || 2x CZ TR150 480GB RAID 0 || BeQuiet DarkRock Pro

Permalänk

Varför kan du inte lägga in en Thread.sleep(100) i metoderna som kör sorteringen?

public void quicksort() { Thread.sleep(100); ... <resten av koden> }

Det är ju hur algoritmerna är utformade som gör dem olika snabba, inte hur koden är optimerad (om du inte har skrivit riktigt dålig kod till nån av dem).

Visa signatur

○ Citera

Permalänk
Medlem
Skrivet av lollol7:

Frågade min lärare idag så svarade han typ "äh, ni behöver inte kunna så mycket så bara du får fram ett program som ritar upp dom ungefär lika snabbt som annars så är det lungt"

Typexempel för kvalitén på svensk undervisning...

Se det som en övning i att förstå algoritmerna bättre (och lära dig programmera vettigare) genom att bryta upp algoritmerna så att du kan ha en tråd som tar ett steg i taget genom varje algoritm en efter en. För det är väl det du vill se? Att du gör extra arbete spelar ju ingen roll i så fall.

Visa signatur

"Some poor, phoneless fool is probably sitting next to a waterfall somewhere, totally unaware of how angry and scared he's supposed to be." - Duncan Trussell

Permalänk
Medlem
Skrivet av Deliberation:

Varför kan du inte lägga in en Thread.sleep(100) i metoderna som kör sorteringen?

public void quicksort() { Thread.sleep(100); ... <resten av koden> }

Det är ju hur algoritmerna är utformade som gör dem olika snabba, inte hur koden är optimerad (om du inte har skrivit riktigt dålig kod till nån av dem).

Mjoo, men beroende på var jag lägger in den påverkar det ju på olika sätt. T.ex. om du lägger in den i loopen i insertionsort så kanske den sleepas n^2 gånger, medan om jag lägger den precis i början av metoden för mergesort kanske den bara körs log(n) gånger. Detta gör ju att även fast mergesort gör massa övrigt. Lägger jag den på fler ställen så kan det bli så att den körs "för mycket" så att i fall då mergesort bör vinna (t.ex. nästan sorterade elemnet i omvänd ordning) så förlorar den ändå.

Skrivet av gibbon_:

Typexempel för kvalitén på svensk undervisning...

Se det som en övning i att förstå algoritmerna bättre (och lära dig programmera vettigare) genom att bryta upp algoritmerna så att du kan ha en tråd som tar ett steg i taget genom varje algoritm en efter en. För det är väl det du vill se? Att du gör extra arbete spelar ju ingen roll i så fall.

Men ett "steg" kan ju vara olika långt. Att merga två arrayer i merge är ju ett större steg än att jämföra två tal i insertion. Att bara kopiera ett element från en array till en annan är dock mindre. Att då bara pausa mellan t.ex. var 5:e kopiering innebär ju då att jag måste ha en while(counter<5) som då tar lika lång tid som en if att kolla och då går ju koden mycket trögare.

Så den lösningen jag har just nu är att jag lagt in några sleeps (en i insertion, 4st i merge på olika platser m.m.) och då fått dom att i förhållande till varandra hamna i samma ordning (att merge vinner för omvänt sorterade värden, insertion vinner för nästan sorterade och quick vinner för random) men det känns fortfarande som ett lite väl dumt sätt att göra det på, därför jag frågar om det finns något smartare sätt

Visa signatur

In the end what separates a man from a slave?
Money? Power? No... A man chooses, a slave obeys.
ASUS Z170M-PLUS || Intel Core i7 6700k @ 4,7GHz || 64GB 2133MHz Corsair RAM || MSI NVIDIA RTX 2070 Gaming Z 8GB || Bifenix Prodigy M || 2x CZ TR150 480GB RAID 0 || BeQuiet DarkRock Pro

Permalänk
Medlem
Skrivet av lollol7:

Mjoo, men beroende på var jag lägger in den påverkar det ju på olika sätt. T.ex. om du lägger in den i loopen i insertionsort så kanske den sleepas n^2 gånger, medan om jag lägger den precis i början av metoden för mergesort kanske den bara körs log(n) gånger. Detta gör ju att även fast mergesort gör massa övrigt. Lägger jag den på fler ställen så kan det bli så att den körs "för mycket" så att i fall då mergesort bör vinna (t.ex. nästan sorterade elemnet i omvänd ordning) så förlorar den ändå.

Sorteringsalgoritmer jämförs för det allra mesta efter deras order of-effektivitet och inte implementationsberoende faktorer. Det vill säga, om algoritm A tar 10 vändor för att sortera en viss struktur och algoritm B behöver 12, så anses algoritm A vara den effektivaste även om komplexiteten vid implementation gör att dess 10 vändor tar 150 ms medan algoritm B tar 120.

Därför bör fördröjningen ske efter varje 'vända', dvs efter varje förändring i strukturen. Beroende på hur implementationen är gjord blir det en sleep i slutet av varje loop och/eller en sleep innan varje rekursivt anrop. Om det är stor skillnad mellan algoritmernas implementationseffektivitet kan du implementera en metod som sover upp till [n] millisekunder:

import static System.currentTimeMillis; abstract class AbstractSort { private long lastSleep = currentTimeMillis(); public final void delayThread() { long now = currentTimeMillis(); long diff = now - lastSleep; assert diff < 100 : "sorteringssteget tog för lång tid"; Thread.sleep(100 - diff); lastSleep = currentTimeMillis(); } abstract public int[] sort(int[] collection); }

Visa signatur

Kom-pa-TI-bilitet