天眼哥 發表於 2026-4-12 09:43:00

Java中的线程

<h2 id="什么是线程">什么是线程?</h2>
<ul>
<li>线程(Thread)是程序执行流的最小单位。</li>
<li>在 Java 中,一个线程代表一个独立的执行路径,它运行在进程(Process)内部。</li>
<li>进程 vs 线程:
<ul>
<li>进程是操作系统分配资源的基本单位(如一个 Java 应用就是一个进程)。</li>
<li>线程是 CPU 调度的基本单位,多个线程共享同一个进程的内存空间(堆、方法区),但各自拥有独立的栈和程序计数器。</li>
</ul>
</li>
</ul>
<blockquote>
<p>多线程程序在更低一层扩展了多任务的概念:单个程序看起来在同时完成多个任务。每个任务在一个线程(thread)中执行,线程是控制线程的简称。如果一个程序可以同时运行多个线程,则称这个程序是多线程的(multithreaded)。</p>
</blockquote>
<h2 id="在java中创建线程">在Java中创建线程</h2>
<p>线程的创建有三种方式:</p>
<h3 id="21-继承thread类重写run方法">2.1 继承Thread类,重写run方法</h3>
<ol>
<li>创建一个继承Thread的类,重写run方法</li>
<li>在main方法中创建该类的对象,对象使用start方法启动线程,并开始执行该线程的任务</li>
<li>如果直接调用run方法,只会让当前线程执行任务</li>
</ol>
<pre><code class="language-java">public class ThreadTest {
    private static final int STEP = 100;

    public static void main(String[] args) {
      MyJob job = new MyJob();
      job.start();
      for (int i = 0; i &lt; STEP; i++) {
            System.out.println("main run: " + i);
      }
    }
}

class MyJob extends Thread {
    private static final int STEP = 100;

    @Override
    public void run() {
      for (int i = 0; i &lt; STEP; i++) {
            System.out.println("job run: " + i);
      }
    }
}

</code></pre>
<h3 id="22-实现runnable接口重写run方法">2.2 实现Runnable接口,重写run方法</h3>
<ol>
<li>创建一个类实现Runnable接口,重写run方法</li>
<li>在main方法中创建该类的对象</li>
<li>创建Thread类的对象,构造方法中传入Runnable接口的实现类对象</li>
<li>Thread类的对象使用start方法启动线程,并开始执行该线程的任务</li>
<li>同样,如果直接调用run方法,只会让当前线程执行任务</li>
</ol>
<pre><code class="language-java">public class RunnableTest {
    private static final int STEP = 100;

    public static void main(String[] args) {
      MyAnotherJob job = new MyAnotherJob();
      Thread t = new Thread(job);
      t.start();
      for (int i = 0; i &lt; STEP; i++) {
            System.out.println("main run: " + i);
      }
    }
}

class MyAnotherJob implements Runnable {
    private static final int STEP = 100;

    @Override
    public void run() {
      for (int i = 0; i &lt; STEP; i++) {
            System.out.println("job run: " + i);
      }
    }
}

</code></pre>
<h3 id="23-实现callable接口重写call方法配合futuretask使用">2.3 实现Callable接口,重写call方法,配合FutureTask使用</h3>
<p>Callable一般用于有返回结果的非阻塞的执行方法<br>
<strong>同步非阻塞</strong></p>
<ol>
<li>创建一个类实现 <code>Callable&lt;V&gt;</code> 接口</li>
</ol>
<ul>
<li>泛型 V 表示 call() 方法的返回类型(如 String、Integer 等)。</li>
<li>重写 call() 方法,在其中编写需要在线程中执行的逻辑,并返回结果。</li>
</ul>
<ol start="2">
<li>创建 Callable 实例</li>
</ol>
<ul>
<li>即你自定义的实现了 Callable 的类的对象。</li>
</ul>
<ol start="3">
<li>将 Callable 实例包装进 FutureTask</li>
</ol>
<ul>
<li>FutureTask 是一个包装器,它实现了 Runnable 和 Future 接口,既能被线程执行,又能获取结果。</li>
</ul>
<ol start="4">
<li>创建 Thread 对象,传入 FutureTask</li>
</ol>
<ul>
<li>因为 FutureTask 实现了 Runnable,所以可以作为 Thread 的构造参数。</li>
</ul>
<ol start="5">
<li>启动线程(调用 start())</li>
<li>调用 FutureTask.get() 获取线程执行结果</li>
</ol>
<ul>
<li>get() 方法会阻塞当前线程,直到任务完成并返回结果。</li>
<li>如果任务抛出异常,get() 会抛出 ExecutionException。</li>
</ul>
<pre><code class="language-java">import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyTask implements Callable&lt;String&gt; {
    private final long duration; // 模拟耗时操作的时间(毫秒)

    public MyTask(long duration) {
      this.duration = duration;
    }

    @Override
    public String call() throws Exception {
      System.out.println("任务开始执行...");
      Thread.sleep(duration); // 模拟耗时操作
      return "任务完成,耗时 " + duration + " 毫秒";
    }
}

public class CallableExample {
    public static void main(String[] args) {
      Callable&lt;String&gt; callable = new MyTask(2000);

      FutureTask&lt;String&gt; futureTask = new FutureTask&lt;&gt;(callable);

      Thread thread = new Thread(futureTask, "MyThread");

      thread.start();

      System.out.println("主线程继续执行其他任务...");

      try {
            String result = futureTask.get();
            System.out.println("线程返回结果: " + result);
      } catch (Exception e) {
            e.printStackTrace();
      }
    }
}
</code></pre>
<h2 id="多线程三种实现方式的对比">多线程三种实现方式的对比</h2>
<table>
<thead>
<tr>
<th></th>
<th>优点</th>
<th>缺点</th>
</tr>
</thead>
<tbody>
<tr>
<td>继承Thread类</td>
<td>实现简单,可以直接使用Thread类中的方法</td>
<td>不能再继承其他类,扩展性较差</td>
</tr>
<tr>
<td>实现Runnable接口</td>
<td>扩展性强,实现接口的同时可以继承其他类</td>
<td>编程比较复杂,不能使用Thread类的其他方法</td>
</tr>
<tr>
<td>实现Callable接口</td>
<td>扩展性强,实现接口的同时可以继承其他类</td>
<td>编程比较复杂,不能使用Thread类的其他方法</td>
</tr>
</tbody>
</table><br><br>
来源:https://www.cnblogs.com/vitastic/p/19820800
頁: [1]
查看完整版本: Java中的线程