Conceptos básicos y métodos de implementación de multiproceso

1. Conceptos básicos

Programa: Es una colección ordenada de instrucciones y datos, no tiene significado operativo y es un concepto estático.
Proceso: Es un proceso de ejecución de ejecutar un programa, es un concepto dinámico. Es la unidad de asignación de recursos del sistema.

Por lo general, un proceso puede contener varios hilos. El subproceso es la unidad de programación y ejecución de la CPU.
Se simulan muchos subprocesos múltiples. El subproceso múltiple real se refiere a múltiples CPU, es decir, múltiples núcleos, como servidores.
Si se simula un subproceso múltiple, es decir, en el caso de una CPU, la CPU solo puede ejecutar un código en el mismo momento, dado que la conmutación es rápida, habrá una ilusión de ejecución simultánea.

Un hilo es una ruta de ejecución independiente;
cuando el programa se está ejecutando, incluso si no crea un hilo usted mismo, habrá varios hilos en segundo plano, como el hilo principal y el hilo gc;
main () se llama hilo principal, que es la entrada del sistema y se usa para la ejecución. El programa completo:
en un proceso, si se abren varios subprocesos, el planificador programa la ejecución del subproceso. El planificador está
estrechamente relacionado con el sistema operativo y la secuencia no se puede interferir artificialmente.
Cuando se opera en el mismo recurso, habrá un problema de apropiación de recursos, y es necesario agregar control de concurrencia; los
subprocesos traerán una sobrecarga adicional, como el tiempo de programación de la CPU y la sobrecarga de control de concurrencia.
Cada hilo interactúa en su propia memoria de trabajo. Un control inadecuado de la memoria provocará inconsistencias en los datos.

2. 3 formas de realizar subprocesos múltiples

El primer método: heredar la clase Thread, reescribir el método de ejecución (entenderlo)

El código de implementación es el siguiente:

//创建多线程方式一:继承Thread类,重写run方法,调用start方法开启线程
public class TestThread1 extends Thread{
    
    
    @Override
    public void run(){
    
    
        for (int i = 0; i < 1000; i++) {
    
    
            System.out.println("看代码--"+i);
        }
    }

    public static void main(String[] args) {
    
    
        //main线程,主线程

        //创建线程对象,并调用start()方法启动线程
        TestThread1 thread1 = new TestThread1();
        thread1.start();

        for (int i = 0; i < 1000; i++) {
    
    
            System.out.println("学习多线程--"+i);
        }
    }
}

El segundo método: implementar la interfaz Runnable y reescribir el método de ejecución (énfasis)

El código de implementación es el siguiente:

//创建多线程方式二:实现Runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread2 implements Runnable{
    
    
    @Override
    public void run(){
    
    
        for (int i = 0; i < 1000; i++) {
    
    
            System.out.println("看代码--"+i);
        }
    }

    public static void main(String[] args) {
    
    
        //main线程,主线程

        //创建Runnable接口的实现类对象
        TestThread2 testThread2 = new TestThread2();

        //创建线程对象,通过线程对象来开启我们的线程,代理
        Thread thread = new Thread(testThread2);
        thread.start();

        for (int i = 0; i < 1000; i++) {
    
    
            System.out.println("学习多线程--"+i);
        }
    }
}

El tercer método: para implementar la interfaz invocable (puede entenderlo) para
implementar la interfaz invocable, el tipo de valor de retorno debe
reescribirse, el método de llamada debe lanzarse,
se
crea el objeto de destino y se crea el servicio de ejecución: ExecutorService ser = Executors.newFixedThreadPool (1);
Enviar para ejecución: Futureresult1 = ser.submit (t1);
Obtener el resultado: boolean r1 = result1.get ()
Cerrar el servicio: ser.shutdownNow ();

Ejercicio de código: la tortuga y la liebre:

//模拟龟兔赛跑
public class Race implements Runnable{
    
    

    //定义胜利者
    private static String winner;

    @Override
    public void run() {
    
    
        for (int i = 0; i <= 100; i++) {
    
    

            //模拟兔子休息。每隔10毫秒
            if (Thread.currentThread().getName().equals("兔子") && i%10==0){
    
    
                try {
    
    
                    Thread.sleep(10);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }

            //判断比赛是否结束
            boolean flag = gameOver(i);
            if(flag)
                break;
            System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");
        }
    }

    //判断是否完成比赛
    private boolean gameOver(int steps){
    
    
        if(winner != null) //已经有winner了
            return true;
        if(steps == 100){
    
    
            winner = Thread.currentThread().getName();
            System.out.println("winner is "+ winner);
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
    
    
        Race race = new Race();

        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();
    }
}

3. Método del hilo

setPriority(int newPriority)Cambia la prioridad del subproceso.
static void sleep(long millis)Deja que el subproceso actualmente en ejecución duerma durante el número especificado de milisegundos.
void join()Espera a que el subproceso termine.
static void yield()Pausa el objeto del subproceso que se está ejecutando actualmente y ejecuta otros subprocesos.
void interrupt()Interrumpe el subproceso. No uses esto para
boolean isAlive()probar si el subproceso está activo.

Probar prioridad de hilo (prioridad)

De acuerdo con los resultados de múltiples ejecuciones: el hilo principal se ejecuta primero cada vez. Y los otros 3,
conocidos aleatoriamente : la prioridad del hilo principal es 5, no establecido (predeterminado) también es 5. La prioridad baja es solo la baja probabilidad de ser llamado, no es que no se llame a la prioridad baja, todo depende de la programación de la CPU.

Ejercicio de código:

package com.lu.state;

//测试线程优先级
//根据多次运行结果:main线程每次是都是最先运行。而另外3个,随机
//可知:main线程优先级是5,不设置(默认)也是5。优先级低只是被调用的概率低,
//并不是优先级低就不会被调用了,这都要看CPU的调度
public class TestPriority{
    
    
    public static void main(String[] args) {
    
    
        //主线程默认优先级
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());

        MyPriority myPriority = new MyPriority();
        Thread t0 = new Thread(myPriority);
        Thread t1 = new Thread(myPriority);
        Thread t2 = new Thread(myPriority);

        //先设置优先级在启动
        t1.setPriority(1);
        t2.setPriority(10);

        t1.start();
        t2.start();
        t0.start();
    }
}
class MyPriority implements Runnable{
    
    
    @Override
    public void run() {
    
    
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
    }
}

Subproceso del demonio El
subproceso se divide en subproceso del usuario y subproceso del demonio. La
máquina virtual debe garantizar que se ejecute el subproceso del usuario. La
máquina virtual no necesita esperar a que se ejecute el subproceso del demonio. Por
ejemplo, el fondo registra los registros de operaciones, monitorea la memoria y espera la recolección de basura.

Ejercicio de código:

package com.lu.state;

//测试守护线程
//上帝守护你
public class TestDaemon {
    
    
    public static void main(String[] args) {
    
    
        God god = new God();
        You you = new You();

        Thread thread = new Thread(god);
        thread.setDaemon(true);//默认是false,表示是用户线程,正常的线程都是用户线程...

        thread.start();//上帝守护线程启动

        new Thread(you).start();//你,用户线程启动

    }
}

//上帝
class God implements Runnable{
    
    
    @Override
    public void run() {
    
    
        while (true){
    
    
            System.out.println("上帝保佑着你");
        }
    }
}

//你
class You implements Runnable{
    
    
    @Override
    public void run() {
    
    
        for (int i = 0; i < 36500; i++) {
    
    
            System.out.println("你一生都开心的活着");
        }
        System.out.println("goodbye world!");
    }
}

Supongo que te gusta

Origin blog.csdn.net/qq_42524288/article/details/105783409
Recomendado
Clasificación