Avatar billede mtilsted Nybegynder
04. august 2001 - 16:49 Der er 4 kommentarer og
1 løsning

Hvor Thread unsafe er swing.

Jeg kan ikke helt finde ud af præsis hvor thread unsafe swing er.

Eksemple et:

En JFrame kaldet JF indeholder 2 JTextField
kaldet F1 og F2.
Programmet bestaar af 2 Threads kaldet T1 og T2.

Hvad sker der saa hvis T1 kalder J1.setText(\"Blaa\"); samtidig med at T2 kalder J2.setBackground (Color.black);

Eksempel 2:

Programmet bestaar af de samme dele som i eksempel 1.
Hvad sker der saa hvis T1 kalder JF.add(new JTextField(\"et nyt field\"));
samtidig med at T2 kalder F2.setText(\"Something else\");

Avatar billede lbhansen Nybegynder
04. august 2001 - 18:59 #1
Man snakker om Thread unsafty, når flere threads prøver på at kalde samme metode, eller prøver på at ændre samme variabel.

Der bliver ikke kaldt samme metode, eller ændret fællesvariable i nogen af tilfældende
Avatar billede logical Nybegynder
05. august 2001 - 08:28 #2
Thread asfe er beskyttelse mod det notoriske begreb race conditions, altså betingelser hvor forskellig afvikling af koden giver forskellige (rigtige+forkerte) resultater, hvor der som minimum er tre betingelser opfyldt:
Der er minimum 2 tråde
Trådene tilgår fælles data    (Uden synkronisering)
Mindst en af dem skriver til data

Hvis ikke disse betingelser er tilstede vil der ikke kunne opstå race conditions.

Der hvor swing har behvor for at være safe skyldes nogle basale ting i et gui miljø. Hvis jeg f.eks. har en firkant:
xxxxxxxx
x      x
x      x
x      x
x      x
xxxxxxxx

Så tager det mig X tid at tegne den på skærmen. Det ville så være upraktisk hvis den blev formindsket til f.eks. 2x2 under optegningen, så kunne det f.eks. se sådan ud:
xxxxxxxx
x      x
x      x
x      x
              <---- Her er den resizet.

Hvis vi skal beskytte os mod det, har vi to strategier. Enten skal alt tilgang til mange variable være synkrone, eller vi skal max have en tråd.

Løsning 1 vil betyde, at hvergang vi aktiverer en metode, vil der skulle ske en synkronisering. En synkronisering koster en del millisekunder hver gang.

Hvis vi kun har en tråd, kommer der ingen problemer, men så bliver alle events m.m. behandlet i en tråd. Dvs. blandt de mange update request events kommer alle kaldene til actionPerformed, valueChanged, etc. Det gør, at paint request faktisk ikke kan behandles så hurtigt efter hinanden (Hvorfor det ikke har været velegnet til f.eks. animationer).

Af de to løsningsmuligheder har man valgt nr to, inklusiv fordele og ulemper. Det betyder at man bør lave så lidt kode så muligt i sine listener, og hvis det ikke er muligt, lav det i en baggrundsttråd (Var det ikke også det jeg sagde sidst?).

lbhansen>> Lyt nu med her, for der er lige noget du mangler at forstå :-)

Men for at vende tilbage til dine spørgsmål, så er svarene:
1) Formodentlig ingenting
2) Ingenting

Dine tråde T1 og T2 arbejder ikke i de to eksempler på nogle fælles data, og der er derfor ingen race conditions mellem dine 2 tråde. Men jeg siger formodentlig fordi der er jo den tredie tråd, guitråden (G).

Så har vi 2 tråde (f.eks. T1 og G) som arbejder på et tekstfelt J2, hvoraf en af dem skriver (.setBackground()). Potentielt set kan baggrunden blive sat cirka halvejs igennem en optegning af dit JTextField, med et besynderligt resultat til følge.

mht. setText, så bruger man dem ca følgende:
component {
public void setText(String s) {
  text = s;
}
public void paint(Graphics g) {
  g.drawString(text, x, y);
}
}

Og fordi man ikke manipulerer inde i en String, men sætter en reference til det ene objekt(den ene tekst) eller det andet objekt(den anden tekst), så bliver det tidspunktet der afgør om det er den ene eller den anden tekst, der bliver vist ved denne gentegning. Efter man sætter teksten kalder man så typisk implicit eller eksplicit revalidate(), som poster et repaint request på event køen.

Det samme gør sig gældende for din add. Enten er den med i listen af komponenter, som skal tegnes eller også er den ikke.

Hvis du vil bevise noget, så prøv følgende klasse:
public class CharCanvas extends Canvas {
  private char[] chars = new char[20];

  public void setChars(char[] ch) {
    for (int i = 0 ; i < ch.length ; i++)
      chars[i] = ch[i];              // Index Exceptions are not my consern
  }

  public void paint(Graphics g) {
    for (int i = 0 ; i < chars.length ; i++)
      g.drawString(\"\"+chars[i], 100+(10*i), 100)
  }
}

Og kald det fra et par tråde udefra. Hvor de f.eks. sætter forskellige tekster med forskellige intervaller(0-3 ms) og kalder repaint.
Avatar billede lbhansen Nybegynder
05. august 2001 - 08:40 #3
Logical >> Liver er en læreprocess. Det har jeg da indset, jeg læser da også de fleste af dine besvarelser, det er rart at have nogle velformulerede gutter på forummet :)
Avatar billede logical Nybegynder
05. august 2001 - 11:34 #4
lbhansen>> Du havde bare glemt GUItråden i dine tanken. Pas på med det.
Desværre har jeg for travlt i øjeblikket til at hjælpe alle på rette vej, men jeg kan da se, at du også får gjort en god indsats :-)
Avatar billede lbhansen Nybegynder
05. august 2001 - 11:37 #5
Logical >> Ja, der har været lidt lavvande på arbejdet, så jeg har brugt en del tid herinde:)

Det er meget god måde at hjælpe andre på, og samtidig holde meget af det vedlige, som man går og glemmer hen over tid.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester