preguntas de la entrevista relacionados con la programación concurrentes

1. La relación entre los procesos e hilos así como corrutinas

  proceso:

    proceso sencillo de entender es que el programa que utilizamos normalmente, como QQ, navegador, disco de red y así sucesivamente. El proceso tiene su propio espacio de direcciones de memoria independiente,

    Tenemos más de un hilo.

  Tema:

    Hilo puede ser entendida como un proceso ligero, es la unidad más pequeña de la ejecución del programa. Después se inicia un proceso, se generará un hilo principal defecto,

    El hilo principal puede crear múltiples hilos niño,

            

 

              

 

 

       

 

 

 

  HS:

      SA, también llamado micro-hilos, triturar. Hiap Seng es un hilo de ejecución, pero un poco como una ejecución de subprocesos múltiples, de alta eficiencia en el SA de implementación

      En pocas palabras Hiap Seng es una versión mejorada de los procesos y subprocesos, procesos beben hilos se enfrentan con el problema de la conmutación dentro del modo núcleo y modo de usuario mientras

    Pasar mucho tiempo para cambiar, y los logros de la Asociación es el control del usuario sobre cuándo cambiar, ya no hay necesidad de caer en el sistema de modo de núcleo.

 

  Un programa tiene al menos un proceso, un producto de al menos un hilo. Las discusiones no pueden ejecutar de forma independiente, deben existir en conformidad con el proceso.

  SA, a nivel de aplicación (en lugar del sistema operativo) controla el interruptor con el fin de mejorar la eficiencia.


2. La diferencia entre el paralelo y concurrente

  Paralelas (paralelo):

        Se refiere a que al mismo tiempo, una serie de instrucciones ejecutadas simultáneamente en múltiples procesadores. Así que en términos del punto de vista microscópico o macroscópico

        Ambos se llevan a cabo juntos.

        

  resumen:

    Cuando el sistema tiene más de una CPU, entonces es posible hacer funcionar el hilo no concurrente. Cuando una CPU ejecuta un hilo, otro

     La CPU puede ejecutar otro hilo, dos hilos y no aprovechar los recursos de CPU, pueden ser realizados de forma simultánea, que llamamos tal manera paralela (paralelo).

 

 

 


  Concurrencia (concurrencia):

        Al mismo tiempo, sólo se refiere a la ejecución de una instrucción, pero instrucción se ejecuta múltiples hilos rotación rápida, haciendo

        Tiene el efecto de la ejecución simultánea de múltiples hilos en la macro, micro, pero no ejecutados simultáneamente, justo

        El tiempo se divide en varios segmentos, una pluralidad de procesos llevados a cabo rápidamente alterna

            

  resumen:

    Cuando hay múltiples hilos en funcionamiento, si el sistema es sólo una CPU, entonces simplemente no puede ser verdad al mismo tiempo más de un hilo,

    Sólo puede tiempo de CPU se divide en varios períodos, entonces el período de tiempo asignado a cada hilo de ejecución, en un período de tiempo

    código roscado está en marcha, otros hilos en un estado de suspensión. De esta manera llamamos simultánea (concurrente).

  
En 3.Java manera multiproceso implementaciones de Java multiproceso aplicación, hay cuatro: la herencia de clases de rosca, implementar Ejecutable, implementa la interfaz invocable para crear hilo por hilo envoltorio FutureTask
  

  Uso ExecutorService, rescatable, Futuro se han dado cuenta devuelve el resultado de múltiples hilos.

  Las dos primeras formas en que los hilos no son después de la aplicación del valor de retorno, los dos últimos con un valor de retorno.


  1, clase Thread herencia para crear hilos
    en la clase Thread es esencialmente implementa una instancia de interfaz Ejecutable, lo que representa una instancia de un hilo. La única manera de empezar el hilo es método de instancia () por clase Entrada de rosca.

    método start () es un método nativo, se iniciará un nuevo hilo, y ejecuta método run (). Esta es una forma muy sencilla de lograr multi-hilo, a través de sus clases extenderse directamente Hilo,

    Y el método de ejecución de replicación (), puede iniciar un nuevo hilo y ejecutar el método run () define a sí mismo. Por ejemplo:  

public class MyThread extends Thread {  
  public void run() {  
   System.out.println("MyThread.run()");  
  }  
}  
 
MyThread myThread1 = new MyThread();  
MyThread myThread2 = new MyThread();  
myThread1.start();  
myThread2.start(); 

  

  2、实现Runnable接口创建线程
  如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口,如下:  

public class MyThread extends OtherClass implements Runnable {  
  public void run() {  
   System.out.println("MyThread.run()");  
  }  
}  

  为了启动MyThread,需要首先实例化一个Thread,并传入自己的MyThread实例: 

MyThread myThread = new MyThread();  
Thread thread = new Thread(myThread);  
thread.start();  

  3、实现Callable接口通过FutureTask包装器来创建Thread线程

  Callable接口(也只有一个方法)定义如下:     

public interface Callable<V>   { 
  V call() throws Exception;   } 
public class SomeCallable<V> extends OtherClass implements Callable<V> {

    @Override
    public V call() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

}
Callable<V> oneCallable = new SomeCallable<V>();   
//由Callable<Integer>创建一个FutureTask<Integer>对象:   
FutureTask<V> oneTask = new FutureTask<V>(oneCallable);   
//注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口。 
  //由FutureTask<Integer>创建一个Thread对象:   
Thread oneThread = new Thread(oneTask);   
oneThread.start();   
//至此,一个线程就创建完成了。

 

4.Callable和Future模式

 https://www.cnblogs.com/szhhhh/p/12553278.html

5.线程池创建的方式(一般不适用Excecutors.nexxxx创建,一般使用ThreadPoolExecutor)

  Java通过Executors(jdk1.5并发包)提供四种线程池,分别为:
  newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。  

public static void main(String[] args) {
        //1.创建可缓存的线程池,可重复利用
        ExecutorService newExecutorService = Executors.newCachedThreadPool();
        //创建了10个线程
        for (int i = 0; i < 10; i++) {
            int temp = i;
            newExecutorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("threadName;"+Thread.currentThread().getName()+",i"+temp);
                }
            });
        }

    }

 


  newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

 public static void main(String[] args) {
        //1.创建可固定长度的线程池
        ExecutorService newExecutorService = Executors.newFixedThreadPool(3);
        //创建了10个线程
        for (int i = 0; i < 10; i++) {
            int temp = i;
            newExecutorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("threadName;"+Thread.currentThread().getName()+",i"+temp);
                }
            });
        }

    }

 


  newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

 public static void main(String[] args) {
        //1.创建可定时线程池
        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5);
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            newScheduledThreadPool.schedule(new Runnable() {
                public void run() {
                    System.out.println("i:" + temp);
                }
            }, 3, TimeUnit.SECONDS);
        }

    }

 


  newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

public static void main(String[] args) {
        //1.创建单线程
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            newSingleThreadExecutor.execute(new Runnable() {

                @Override
                public void run() {
                    System.out.println("index:" + index);
                    try {
                        Thread.sleep(200);
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                }
            });
        }
        newSingleThreadExecutor.shutdown();
    }

 


6.Java当中线程状态有哪些

  1. 创建状态:在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。

  2.就绪状态:当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,

    此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。

  3.运行状态:线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。

  4.阻塞状态:线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。

  5.死亡状态:如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

 

 

7.多线程中的常用方法  

  7.1 public void start()  使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

  7.2 public void run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。

  7.3. public final void setName(String name) 改变线程名称,使之与参数 name 相同

  7.4 public final void setPriority(int piority) 更改线程的优先级。

  7.5 public final void setDaemon(boolean on) 将该线程标记为守护线程或用户线程。

  7.6 public final void join(long millisec) 等待该线程终止的时间最长为 millis 毫秒。

  7.7 public void interrupt() 中断线程。

  7.8 public final boolean isAlive() 测试线程是否处于活动状态。

  7.9 public static void static yield() 暂停当前正在执行的线程对象,并执行其他线程。

  7.10 public static void sleep(long millisec) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。

  7.11 public static Thread currentThread() 返回对当前正在执行的线程对象的引用。

  

 

 

 


8.线程状态流程图
    
9.volatile关键字有什么用途,和Synchronize有什么区别

  volatile:

    volatile用来修饰变量例如:Thread类里面的表示名字的字符数组其作用是保证数据的可见性和有序性,但它并不能保证数据的原子性

    

 

 

 

    因为volatile不能保证原子性,所以就需要关键字 synchronized

  synchronized:

    它用于修饰代码块和方法,可以弥补volatile关键字的不足,即它能保证对数据操作的原子性,在多个线程对数据进行操作时,保证线程的安全

  小结:    

    1. 修饰对象不同,volatile用于修饰变量,synchronized用与对语句和方法加锁;
    2. 各自作用不同,volatile保证数据的可见性和有序性,但它并不能保证数据的原子性,synchronized可以保证原子性;
    3. volatile不会造成线程堵塞,而synchronized会造成线程堵塞;

  脏读:

    脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,

    另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,

    依据脏数据所做的操作可能是不正确的。

10.指令重排和先行发生原则
  指令重排:

     在计算机执行指令的顺序在经过程序编译器编译之后形成的指令序列,一般而言,这个指令序列是会输出确定的结果;

    以确保每一次的执行都有确定的结果。但是,一般情况下,CPU和编译器为了提升程序执行的效率,会按照一定的规则

    允许进行指令优化,在某些情况下,这种优化会带来一些执行的逻辑问题,主要的原因是代码逻辑之间是存在一定的先后顺序,

    在并发执行情况下,会发生二义性,即按照不同的执行逻辑,会得到不同的结果信息。

  先行发生原则 :

    先行发生是Java内存模型中定义的两项操作之间的偏序关系,如果说操作A先行发生于操作B,

    就是说A产生的影响能被B观察到,“影响”包括修改了内存中的共享变量值、发送了消息、调用了方法等。

    例如:   

// 线程A中执行
i = 1;

// 线程B中执行
j = i;

// 线程C中执行
i = 2;

  如果说线程A是先行发生于线程B的,那么可以确定在线程B执行之后 j=1,因为根据先行发生原则,A操作 i = 1 的结果可以被B观察到,并且线程C还没有执行。


11.并发编程线程安全三要素

  当多个线程要共享一个实例对象的值得时候,那么在考虑安全的多线程并发编程时就要

  保证下面3个要素:     

    原子性(Synchronized, Lock):

      即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

    有序性(Volatile,Synchronized, Lock)

      即程序执行的顺序按照代码的先后顺序执行。

    可见性(Volatile,Synchronized,Lock):

      指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

      当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取共享变量时,它会去内存中读取新值。



12.进程和线程间调度算法:

  1. 先来先服务(队列)

  2. 最短优先(优先队列)

  3. 高优先权优先调度算

    3.1 优先权调度算法的类型

    3.2 高响应比优先调度算法

  4. 基于时间片的轮转调度算法

    4.1 时间片轮转法

    4.2  多级反馈队列调度算法

  5. 电梯调度算法


13.Java开发中用过哪些锁:

  乐观锁:

      顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间

    别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,在Java中java.util.concurrent.atomic、

    包下面的原子变量类就是使用了乐观锁的一种实现方式CAS(Compare and Swap 比较并交换)实现的。

  悲观锁:

      总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,

    这样别人想拿这个数据就会阻塞直到它拿到锁。比如Java里面的同步原语synchronized关键字的实现就是悲观锁。

  

  独享锁:

      是指该锁一次只能被一个线程所持有。

  共享锁:

      是指该锁可被多个线程所持有。

  

  互斥锁:

      在Java中的具体实现就是ReentrantLock。

  读写锁:

      在Java中的具体实现就是ReadWriteLock。

  cerradura de reentrada:

      También conocido como cerraduras recursivas, se refiere al mismo hilo adquiere el bloqueo del método de capa exterior cuando la cerradura obtendrá automáticamente en el método interno.

  

  cerraduras justas:

      Se refiere a una pluralidad de hebras de la aplicación con el fin de adquirir el pestillo de la cerradura.

  Bloqueo injusta:

      Se refiere a la orden de varios subprocesos para obtener el bloqueo no es el fin de aplicar el bloqueo, es posible aplicar el hilo después de prioridad hilo para adquirir el bloqueo de la aplicación previa. Una posible inversión causa prioridad o el hambre.

  segmentos de bloqueo:

      Un diseño de la cerradura no es en realidad una cerradura en particular, para ConcurrentHashMap, su aplicación es complicada para conseguir un funcionamiento concurrente eficiente de la cerradura en forma de segmentos.

  Las cerraduras de vuelta:

      Se refiere al intento de adquirir el hilo de bloqueo no bloquea de inmediato, en lugar de utilizar una manera circular para tratar de adquirir el bloqueo, este beneficio es la reducción del consumo de cambio de contexto hilo, el inconveniente es que el ciclo de la CPU va a consumir. Distribuido en:  Bloqueo distribuido:


 
 

      Bloqueo distribuida es un acceso común a los recursos compartidos entre diferentes sistemas o sistema de control distribuido para lograr la cerradura, si un recurso se comparte entre diferentes sistemas o diferentes hosts del mismo sistema,

      Menudo se necesitan para ser mutuamente excluyentes para evitar la interferencia entre sí para garantizar la coherencia.
 Base de datos:
  bloqueo de registro:

     Gran sobrecarga, el bloqueo lento, no habrá un punto muerto; bloqueo de pequeño tamaño, baja probabilidad de conflictos de bloqueo, alta concurrencia

  bloqueo de tabla:

    pequeña sobrecarga, encerrado rápido; no punto muerto; gran fuerza de bloqueo, alta probabilidad de conflictos de bloqueo, el menor grado de concurrencia

  bloqueos de página:

    Costo y la velocidad de bloqueo entre la mesa y la fila cerraduras; habrá un punto muerto; granularidad entre la tabla y fila cerraduras de bloqueo, la concurrencia general de


palabras clave 14.sync entienden
    sincronizada palabra clave resolver los múltiples hilos el acceso a los recursos de sincronización entre, palabra clave sincronizada puede ser garantizada por su método o bloque de código modificado en cualquier momento, sólo un hilo de ejecución.
  

Supongo que te gusta

Origin www.cnblogs.com/szhhhh/p/12592691.html
Recomendado
Clasificación