Un mémo pour mon étude.
Une zone qui stocke la valeur des variables, des instances générées, l'historique des méthodes appelées, etc. L'endroit où ils sont stockés est géré par la JVM. Il existe deux types de zone mémoire
--Empiler --Tas
Il y a.
L'historique des appels de la méthode, la valeur de la variable (variable locale) déclarée dans la méthode. Lorsque la méthode termine le traitement, ces informations sont supprimées de la pile.
Une instance générée à partir d'une classe. Lorsque l'instance n'est plus référencée par aucune variable (modifier la référence, affecter null) De plus, il est automatiquement libéré par le garbage collection de JVM.
Il existe les deux types suivants.
Il existe deux méthodes
--Créez une nouvelle classe qui hérite de la classe Thread --Créez une nouvelle classe qui implémente l'interface Runnable.
Créer une instance d'une classe qui hérite de la classe Thread Appelez la méthode de démarrage de cette instance.
C'est la méthode de démarrage qui s'exécute, Dans la sous-classe qui hérite de la classe Thread, Remplacez la méthode d'exécution de la classe Thread.
La méthode run est exécutée via la méthode start. Les résultats ne sont pas toujours les mêmes et changent à chaque fois qu'ils sont exécutés (parfois non)
class MyTread extends Thread{
//REMARQUE: le niveau ne peut pas être abaissé en dessous du modificateur d'accès défini dans la superclasse.
//Vous ne pouvez pas réduire la visibilité des méthodes héritées de Thread
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("MyTread.run:"+i);
}
}
}
public class SampleProgram{
public static void main(String[] args) {
MyTread mt = new MyTread();
mt.start();
for(int i = 0; i < 5; i++) {
System.out.println("main:"+i);
}
}
}
//résultat
main:0
main:1
main:2
MyTread.run:0
MyTread.run:1
MyTread.run:2
MyTread.run:3
main:3
MyTread.run:4
main:4
Ce n'est pas très différent de l'époque où il a été hérité et fabriqué.
class MyTread implements Runnable{
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("MyTread.run:"+i);
}
}
}
public class SampleProgram{
public static void main(String[] args) {
MyTread mt = new MyTread();
Thread t = new Thread(mt);
t.start();
for(int i = 0; i < 5; i++) {
System.out.println("main:"+i);
}
}
}
Arrêtez le traitement des threads pendant un certain temps. L'unité est la milliseconde. 1000: 1 seconde 2000: 2 secondes
En micro secondes 1000000: 1 seconde
La méthode Thread.sleep peut lever une exception de type InterruptedException. Je dois l'attraper.
public class SampleProgram{
public static void main(String[] args) {
for(int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("main:"+i);
}
}
}
//Je l'ai essayé avec celui qui implémentait l'interface Runnable
class MyTread implements Runnable {
public void run() {
for(int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//Bloc de capture généré automatiquement TODO
e.printStackTrace();
}
System.out.println("MyTread.run:"+i);
}
}
}
public class SampleProgram{
public static void main(String[] args) {
MyTread mt = new MyTread();
Thread t = new Thread(mt);
t.start();
for(int i = 0; i < 5; i++) {
System.out.println("main:"+i);
}
}
}
join()
Vous pouvez attendre le traitement du thread.
Parce que la méthode de jointure peut lever une exception de type InterruptedException Je dois l'attraper.
Une fois que tout le traitement de la classe MyTread est terminé, le traitement principal est exécuté.
class MyTread implements Runnable {
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("MyTread.run:"+i);
}
}
}
public class SampleProgram{
//Maintenant jetons.
public static void main(String[] args) throws InterruptedException {
MyTread mt = new MyTread();
Thread t = new Thread(mt);
t.start();
t.join();
for(int i = 0; i < 5; i++) {
System.out.println("main:"+i);
}
}
}
Lorsque le traitement de la méthode d'exécution est terminé, le traitement de ce thread est terminé. Hmm ... laissons ça pour le moment.
Lors de l'exécution dans plusieurs threads, si plusieurs threads partagent la même valeur de variable Des incohérences peuvent survenir.
Ce qui suit est un programme dont le montant total sera de 1000000 yens
class Bank{
static int money = 0;
static void addOneYen() {
money++;
}
}
class Customer extends Thread{
public void run() {
for(int i = 0; i < 10000; i++) {
Bank.addOneYen();
}
}
}
public class MultiThreadEx {
public static void main(String[] args) {
Customer[] customers = new Customer[100];
for(int i = 0; i < 100; i++) {
customers[i] = new Customer();
customers[i].start();
}
for(int i = 0; i < 100; i++) {
try {
customers[i].join();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Bank.money["+Bank.money+"]");
}
}
//résultat
Bank.money[628887]
Parce qu'il n'y a pas de cohérence entre chaque menace au moment du référencement / de la mise à jour du montant actuel. Le montant total tourne mal. Dans un tel cas, ajoutez "synchronized" avant la méthode addOneYen.
static synchronized void addOneYen() {
money++;
}
Si vous préfixez la méthode avec synchronized, vous ne pouvez exécuter qu'un seul thread à la fois. Lorsqu'une menace est en cours de traitement, l'autre menace attend son tour.
Recommended Posts