Java学习_多线程

来源:互联网 发布:java读取csv文件内容 编辑:程序博客网 时间:2024/06/11 20:52
  1. 线程安全
    在代码所在的进程中有多个线程同时在执行,这些进程都会使用这段代码,在执行的过程中,每次的运行结果和单线程运行时的结果是一致的,而且其他变量的值和预期也是一样的,则是线程安全的。
    线程安全是由全局变量和静态变量引起的,若多个线程对同一个变量进行写操作,就要考虑线程同步的问题。
    多线程可以将一个程序划分为多个任务,彼此独立工作,方便有效地使用处理器和用户时间。

  2. 多线程的两种创建方式
    1)、自己重写一个线程类继承 java.lang.Thread 类。
    2、直接实现 Runnable 接口来重写 run()方法实现线程。

  3. 几种方法的区别
    1)、 sleep()方法是Thread类(线程类)的方法,使当前线程暂停执行指定的时间,把执行机会让给其他线程,但不会释放对象锁,在时间到了之后会自动恢复。
    2)、 wait()方法是Object类的方法,当前线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法后本线程才进入对象锁定池准备获得对象锁进入运行状态。
    3)、 yield()方法只是让出自己的CPU时间片,并且立即进入Runnable状态参与CPU时间竞争,而sleep()进入blocked状态,等时间结束之后才进入Runnable状态参与竞争CPU时间片。

  4. volatile关键字的作用
    1)、保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这个新值对其他线程是立即可见的。
    2)、禁止指令重新排序。

  5. volatile和synchronize关键字比较
    1)volatile关键字告诉jvm这个值是不确定的,需要从主存中读取;
    synchronize则是锁定当前变量,只有当前线程可以访问这个变量,其他线程访问这个变量是会被阻塞的。
    2)volatile关键字只能用在变量级;
    synchronize则可以用在变量,方法,类级别。
    3)volatile只能保证变量的修改可见性,不能保证原子性;
    synchronize不仅可以保证修改可见性,还可以保证原子性。
    4)volatile不会造成线程阻塞;
    synchronize会造成线程阻塞。
    5)volatile标记的标量不会被编译器优化;

  6. 实现同步的方法
    实现同步的方式为使用synchronize关键字
    1)同步方法:可以使静态或非静态方法,不能是抽象方法或者接口方法,当一个线程调用这个对象的同步方法时,则这个对象的所有同步方法都被锁定,不能被访问,单可以调用这个类的非同步方法。
    2)同步块:锁定一个指定的对象,来对同步块中的代码进行同步。

  7. synchronize和Java.util.concurrent.locks.lock的区别
    相同:lock和synchronize都实现了线程同步;
    不同:lock比synchronize有更准确的线程语义和更好的性能,synchronize对自动释放锁,而lock需要程序员手动释放锁,并且必须在finally中释放。

  8. 多线程的数据存储
    在  java  的内存模型中每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息。当线程访问某一个对象值得时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存变量的具体值 load 到线 程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值, 在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象 的值就产生变化了。所以当有多个线程对同一个变量进行修改的时候,每一个线程都会有一个变量副本,每个线程修改变量只是临时修改了 自己的副本,当线程结束时再将修改的值写入在主内存中,这样就出现了线程安全问题。

  9. 线程池
    当一个程序在执行的时候若创建大量线程,并在任务结束的时候销毁会造成大量的系统开销,以及过度切换线程的危险,从而导致系统崩溃。
    线程池就是事先将多个线程放到某一个容器中,容器就是线程池。在用户需要使用线程时,不是new一个线程出来,而是在线程池中取出一个空闲的线程为之服务,服务结束之后不结束线程,而是将这个线程放回到线程池中,供下次需要的时候从线程池中取出使用。一个线程只能同时执行一个任务,但可向一个线程池提交多个任务。
    在 JDK 的 java.util.concurrent.Executors 中提供了生成多种线程池的静态方法。e

ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4); ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(4);ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();

然后调用他们的execute方法即可。




0 0
原创粉丝点击