深入理解与应用多线程技术

如果synchronized?作用于代码块,反编译可以看到两个指令:monitorenter、monitorexit , JVM?使用monitorenter和monitorexit?两个指令实现同步;如果作用synchronized?作用于方法,反编译可以看到ACCSYNCHRONIZED?标记 , JVM?通过在方法访问标识符(flags?)中加入ACCSYNCHRONIZED来实现同步功能 。为什么要使用多线程

  1. 提高响应速度:对于耗时操作,使用线程可以避免阻塞主线程,提高应用程序的响应速度 。
  2. 实现并行操作:在多CPU系统中 , 使用线程可以并行处理任务 , 提高CPU利用率 。
  3. 改善程序结构:将一个既长又复杂的进程分为多个线程 , 可以使其成为几个独立或半独立的运行部分,这样有利于程序的修改和理解 。
  4. 方便的通信机制:线程间可以通过共享内存等方式进行通信,比进程间通信更方便、高效 。
创建线程有几种方式?创建线程有四种方式:
  1. 通过继承Thread类来创建线程 。
  2. 通过实现Runnable接口来创建线程 。
  3. 通过实现Callable接口来创建线程 。
  4. 使用Executor框架来创建线程池 。
简单实现public class ThreadTest {public static void mAIn(String[] args) {Thread thread = new MyThread();thread.start();}}class MyThread extends Thread {@Overridepublic void run() {System.out.println("关注公众号:一安未来");}} public class ThreadTest {public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable();Thread thread = new Thread(myRunnable);thread.start();}}class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("关注公众号:一安未来");}} public class ThreadTest {public static void main(String[] args) throws ExecutionException, InterruptedException {MyThreadCallable mc = new MyThreadCallable();FutureTask<Integer> ft = new FutureTask<>(mc);Thread thread = new Thread(ft);thread.start();System.out.println(ft.get());}}class MyThreadCallable implements Callable {@Overridepublic String call()throws Exception {return "关注公众号:一安未来";}}public class ThreadTest {public static void main(String[] args) throws Exception {ThreadPoolExecutor executorOne = new ThreadPoolExecutor(5, 5, 1,TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(20), new CustomizableThreadFactory("Yian-Thread-pool"));executorOne.execute(() -> {System.out.println("关注公众号:一安未来");});//关闭线程池executorOne.shutdown();}}线程和进程的区别线程和进程是操作系统中重要的概念,都是操作系统资源分配的基本单位 , 但它们有一些关键的区别 。
  1. 地址空间和资源拥有:进程是执行中的一个程序,具有自己的地址空间和文件描述符等资源 。线程是在进程中执行的一个单独的执行路径 , 共享进程的地址空间和资源 。
  2. 开销:创建和销毁一个进程需要保存寄存器、栈信息以及进行资源分配和回收等操作,开销较大 。而线程的创建和销毁只需保存寄存器和栈信息,开销较小 。
  3. 通信切换:进程之间必须通过IPC(进程间通信)进行通信 , 切换开销相对较大 。线程之间可以直接共享进程的地址空间和资源,切换开销相对较小 。
  4. 并发性:进程是独立的执行单元,具有自己的调度算法,在并发条件下更加稳定可靠 。而线程共享进程的资源 , 线程之间的调度和同步比较复杂 , 对并发条件的处理需要更多的注意 。
  5. 一对多的关系:一个线程只能属于一个进程,而一个进程可以拥有多个线程 。
Runnable和 Callable有什么区别
  • Runnable接口只有一个需要实现的方法 , 即run() 。当你启动一个线程时,这个run()方法就会被执行 。Runnable的主要问题是它不支持返回结果
  • Callable可以返回结果,也可以抛出异常 。它有一个call()方法,当调用这个方法时,这个方法就会被执行 。
volatile作用,原理主要用于声明变量,以指示该变量可能会被多个线程同时访问,从而防止编译器进行一些优化,确保线程之间能够正确地读写共享变量 。volatile 提供了一种轻量级的同步机制,但它并不能替代 synchronized,因为它无法解决复合操作的原子性问题 。


推荐阅读