Java多线程编程全解析
立即解锁
发布时间: 2025-08-17 02:29:08 阅读量: 2 订阅数: 5 

### Java多线程编程全解析
#### 1. 多线程实现方式
在Java中,实现多线程主要有两种方式:继承`Thread`类和实现`Runnable`接口。
##### 1.1 继承`Thread`类
- **`run`方法的作用**:`run`方法指定了线程要执行的操作,类似于应用程序中的`main`方法。但`run`方法不能直接调用,而是通过调用`start`方法,由`start`方法自动调用`run`方法。
- **线程的构造方法**:`Thread`类有七个构造方法,常用的有`Thread()`和`Thread(String <name>)`。前者系统会自动生成形如`Thread-n`的线程名,后者可以通过参数指定线程名。可以使用`getName`方法获取线程名。
```java
Thread firstThread = new Thread();
Thread secondThread = new Thread("namedThread");
System.out.println(firstThread.getName());
System.out.println(secondThread.getName());
```
输出结果:
```
Thread-0
namedThread
```
- **`sleep`方法**:用于使线程暂停指定的毫秒数,例如`myThread.sleep(1500)`会使线程暂停1.5秒。线程暂停时,其他线程可以执行,暂停时间结束后,线程回到就绪状态等待处理器。
- **`interrupt`方法**:用于中断单个线程,可用于在睡眠线程的睡眠时间到期前将其“唤醒”。由于`sleep`方法在被其他线程中断时会抛出`InterruptedException`异常,因此必须在`try`块中调用。
- **示例代码**:以下是一个简单的示例,两个线程分别显示自己的名称十次,使用`Math.random()`方法生成随机的睡眠时间,避免输出模式单一。
```java
public class ThreadShowName extends Thread
{
public static void main (String[] args)
{
ThreadShowName thread1, thread2;
thread1 = new ThreadShowName();
thread2 = new ThreadShowName();
thread1.start(); //Will call run.
thread2.start(); //Will call run.
}
public void run()
{
int pause;
for (int i=0; i<10; i++)
{
try
{
System.out.println(
getName()+" being executed.");
pause = (int)(Math.random()*3000);
sleep(pause); //0-3 seconds.
}
catch (InterruptedException interruptEx)
{
System.out.println(interruptEx);
}
}
}
}
```
- **不同任务的线程实现**:如果需要线程执行不同的任务,需要为每个线程创建单独的类,并实现各自的`run`方法。例如,一个线程显示“Hello”五次,另一个线程输出整数1 - 5。
```java
public class ThreadHelloCount
{
public static void main(String[] args)
{
HelloThread hello = new HelloThread();
CountThread count = new CountThread();
hello.start();
count.start();
}
}
class HelloThread extends Thread
{
public void run()
{
int pause;
for (int i=0; i<5; i++)
{
try
{
System.out.println("Hello!");
pause = (int)(Math.random()*3000);
sleep(pause);
}
catch (InterruptedException interruptEx)
{
System.out.println(interruptEx);
}
}
}
}
class CountThread extends Thread
{
int pause;
public void run()
{
for (int i=0; i<5; i++)
{
try
{
System.out.println(i);
pause=(int)(Math.random()*3000);
sleep (pause);
}
catch (InterruptedException interruptEx)
{
System.out.println(interruptEx);
}
}
}
}
```
##### 1.2 实现`Runnable`接口
- **实现步骤**:首先创建一个显式实现`Runnable`接口的应用类,然后创建该类的对象,并将其作为参数传递给`Thread`类的构造方法,从而创建线程。`Thread`类有两个构造方法可以实现这一点:`Thread (Runnable <object>)`和`Thread(Runnable <object>, String <name>)`。
- **示例代码**:以下示例与`ThreadShowName`具有相同的效果,但由于线程对象不是`Thread`类的实例,不能直接使用`getName`和`sleep`方法,需要通过`Thread`类的静态方法`currentThread`和`sleep`来实现。
```java
public class RunnableShowName implements Runnable
{
public static void main(String[] args)
{
Thread thread1 =
new Thread(new RunnableShowName());
Thread thread2 =
new Thread(new RunnableShowName());
thread1.start();
thread2.start();
}
public void run()
{
int pause;
for (int i=0; i<10; i++)
{
try
{
System.out.println(
Thread.currentThread().getName()
+ " being executed.");
pause = (int)(Math.random() * 3000);
Thread.sleep(pause);
}
catch (InterruptedException interruptEx)
{
System.out.println(interruptEx);
}
}
}
}
```
也可以将线程对象声明为实现`Runnable`接口的类的属性,在构造方法中创建并启动线程。
```java
public class RunnableHelloCount implements Runnable
{
private Thread thread1, thread2;
public static void main(String[] args)
{
RunnableHelloCount threadDemo =
new RunnableHelloCount();
}
public RunnableHelloCount()
{
thread1 = new Thread(this);
thread2 = new Thread(this);
thread1.start();
thread2.start();
}
public void run()
{
int pause;
for (int i=0; i<10; i++)
{
try
{
System.out.println(
Thread.currentThread().getName()
+ " being executed.");
pause = (int)(Math.random()*3000);
Thread.sleep(pause);
}
catch (InterruptedException interruptEx)
{
System.out.println(interruptEx);
}
}
}
}
```
#### 2. 多线程服务器
传统的服务器程序一次只能处理一个连接,这在实际应用中是不可行的。解决方法有两种:使用非阻塞服务器和使用多线程服务器。在J2SE 1.4之前,Java没有专门的非阻塞I/O支持,因此多线程服务器是唯一可行的选择。
##### 2.1 多线程服务器的优点
- **实现清晰**:将分配连接的任务与处理每个连接的任务分开。
- **健壮性强**:一个连接出现问题不会影响其他连接。
##### 2.2 多线程服务器的基本原理
多线程服务器的基本技术涉及两个阶段的过程:
1. 主线程(在`main`方法中自动运行的线程)为传入的客户端分配单独的线程。
2. 分配给每个客户端的线程通过其`run`方法处理该客户端与服务器之间的所有后续交互。
以下是一个使用多线程的回显服务器示例:
```java
import java.io.*;
import java.net.*;
public class MultiEchoServer
{
private static ServerSocket serverSocket;
private static final int PORT = 1234;
public static void main(String[] args)
throws IOException
{
try
{
serverSocket = new ServerSocket(PORT);
}
catch (IOException ioEx)
{
System.out.println("\nUnable to set up port!");
System.exit(1);
}
do
{
Socket client = serverSocket.accept();
System.out.println("\nNew client accepted.\n");
ClientHandler handler =
new ClientHandler(client);
handler.start();
}while (true);
}
}
class ClientHandler extends Thread
{
pr
```
0
0
复制全文
相关推荐










