Java多线程编程手册_第1页
Java多线程编程手册_第2页
Java多线程编程手册_第3页
Java多线程编程手册_第4页
Java多线程编程手册_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java多线程编程手册一、概述

Java多线程编程是实现并发处理的关键技术,能够显著提高应用程序的性能和响应速度。本手册旨在为开发者提供一套系统性的指导,涵盖多线程基础、常用类库、线程安全、性能优化等方面。通过学习本手册,开发者能够掌握Java多线程编程的核心概念和实践方法。

---

二、多线程基础

(一)线程的基本概念

1.线程与进程的区别

-进程:资源分配的基本单位,包含多个线程。

-线程:CPU调度的基本单位,共享进程资源。

2.线程状态

-新建(New):线程创建后未启动。

-运行(Running):CPU正在执行线程。

-就绪(Ready):线程已准备就绪,等待CPU调度。

-阻塞(Blocked):线程因等待资源或事件而暂停。

-死亡(Terminated):线程执行完毕或异常终止。

(二)线程创建与启动

1.继承Thread类

```java

classMyThreadextendsThread{

publicvoidrun(){

//线程执行内容

}

}

MyThreadthread=newMyThread();

thread.start();

```

2.实现Runnable接口(推荐)

```java

classMyRunnableimplementsRunnable{

publicvoidrun(){

//线程执行内容

}

}

Threadthread=newThread(newMyRunnable());

thread.start();

```

3.使用Callable和Future(带返回值)

```java

classMyCallableimplementsCallable<Integer>{

publicIntegercall()throwsException{

return42;

}

}

ExecutorServiceexecutor=Executors.newSingleThreadExecutor();

Future<Integer>future=executor.submit(newMyCallable());

Integerresult=future.get();

```

(三)线程生命周期管理

1.暂停与恢复

-`Thread.sleep(longmillis)`:线程休眠指定时间。

-`Thread.join()`:当前线程等待目标线程执行完毕。

2.优先级设置

-`setPriority(intpriority)`:设置线程优先级(1-10)。

-`getPriority()`:获取线程优先级。

3.中断管理

-`interrupt()`:中断线程。

-`isInterrupted()`:检查线程是否被中断。

-`Terrupted()`:清除中断状态。

---

三、线程同步机制

(一)同步方法与同步块

1.同步方法

-使用`synchronized`关键字修饰。

```java

synchronizedvoidsynchronizedMethod(){

//代码块

}

```

2.同步块

-作用于代码块或对象。

```java

Objectlock=newObject();

synchronized(lock){

//代码块

}

```

(二)锁机制

1.ReentrantLock

-可中断锁、可公平锁。

```java

ReentrantLocklock=newReentrantLock();

lock.lock();

try{

//代码块

}finally{

lock.unlock();

}

```

2.ReadWriteLock

-读写分离锁,提高并发性能。

```java

ReadWriteLockrwLock=newReentrantReadWriteLock();

rwLock.readLock().lock();

try{

//读取操作

}finally{

rwLock.readLock().unlock();

}

```

(三)原子类

1.基本类型原子类

-`AtomicInteger`,`AtomicLong`等。

```java

AtomicIntegercount=newAtomicInteger(0);

count.incrementAndGet();//count=1

```

2.引用类型原子类

-`AtomicReference`,用于引用类型。

---

四、线程池与任务调度

(一)线程池使用

1.创建线程池

-`Executors.newFixedThreadPool(intnThreads)`:固定大小线程池。

-`Executors.newCachedThreadPool()`:可缓存线程池。

```java

ExecutorServicepool=Executors.newFixedThreadPool(5);

pool.submit(()->System.out.println("Taskexecuted"));

pool.shutdown();

```

2.线程池参数配置

-核心线程数、最大线程数、空闲存活时间、工作队列。

(二)任务调度

1.ScheduledExecutorService

-支持定时任务。

```java

ScheduledExecutorServicescheduler=Executors.newScheduledThreadPool(1);

scheduler.scheduleAtFixedRate(()->System.out.println("Timertask"),0,1,TimeUnit.SECONDS);

```

---

五、线程安全与并发容器

(一)线程安全集合

1.常用线程安全集合

-`ConcurrentHashMap`,`CopyOnWriteArrayList`。

```java

ConcurrentHashMap<String,Integer>map=newConcurrentHashMap<>();

map.put("key",1);

```

(二)并发工具类

1.CountDownLatch

-等待多个线程执行完毕。

```java

CountDownLatchlatch=newCountDownLatch(3);

for(inti=0;i<3;i++){

newThread(()->{

//任务执行

latch.countDown();

}).start();

}

latch.await();

```

2.CyclicBarrier

-多线程互相等待。

```java

CyclicBarrierbarrier=newCyclicBarrier(3,()->System.out.println("Allthreadsreached"));

```

---

六、性能优化建议

1.选择合适的线程池规模

-根据CPU核心数和工作负载调整。

2.避免过度同步

-减少同步块范围,使用原子类替代。

3.使用并发API

-偏向锁(`ReentrantLock`)、并发集合。

---

七、常见问题排查

1.死锁排查

-使用`jstack`分析线程堆栈。

2.资源竞争优化

-减少锁粒度,使用`ReadWriteLock`。

---

八、总结

Java多线程编程涉及多个层面,从基础线程管理到高级并发控制,需要开发者结合实际场景灵活应用。本手册提供了一套完整的实践指南,开发者可通过不断练习和优化,提升并发程序的性能和稳定性。

---

二、多线程基础

(一)线程的基本概念

1.线程与进程的区别

-进程:可以理解为程序的一次执行过程,是系统进行资源分配和调度的基本单位。一个进程可以包含多个线程,这些线程共享进程所拥有的资源,如内存空间、文件句柄等。进程之间通常相互隔离,资源独立。

-线程:是CPU调度的基本单位,比进程更轻量级。线程本身不拥有资源,而是共享所属进程的资源。一个进程至少包含一个线程,即主线程。线程的创建、销毁和切换比进程更快,因此使用多线程可以实现更高效的并发处理。

2.线程状态

-新建(New):当使用`Thread`类或`Runnable`接口创建一个新的线程对象后,该线程就处于新建状态。此时线程尚未被CPU分配执行资源,也没有开始执行。

-可运行(Runnable):当调用线程的`start()`方法后,线程的状态从新建变为可运行。此时线程已经准备好执行,但尚未获得CPU的执行权,处于就绪队列中,等待CPU调度。

-阻塞(Blocked):线程在执行过程中可能会遇到需要等待的情况,例如等待I/O操作完成、等待获取锁等。当线程进入这些等待状态时,其状态变为阻塞。线程阻塞时不会占用CPU资源,直到阻塞条件解除。

-等待(Waiting):线程可以显式地进入等待状态,例如调用`Object.wait()`方法。等待状态的线程需要其他线程调用其`notify()`或`notifyAll()`方法才能退出等待状态。

-时间等待(TimedWaiting):线程可以进入时间等待状态,例如调用`Thread.sleep(longmillis)`方法或`Object.wait(longtimeout)`方法。时间等待状态的线程会在指定的时间后自动退出等待状态。

-终止(Terminated):当线程的`run()`方法执行完毕或线程被强制终止时,线程的状态变为终止。终止状态的线程无法再被激活。

(二)线程创建与启动

1.继承Thread类

-继承`Thread`类是实现线程的一种方式。通过继承`Thread`类,可以创建一个自定义的线程类,并在该类中重写`run()`方法来定义线程的执行逻辑。

-以下是继承`Thread`类创建线程的步骤:

1.定义一个类,继承自`Thread`类。

2.在该类中重写`run()`方法,定义线程的执行内容。

3.创建该类的实例,调用实例的`start()`方法启动线程。

-示例代码:

```java

classMyThreadextendsThread{

//构造方法

publicMyThread(Stringname){

super(name);//设置线程名称

}

//重写run()方法

@Override

publicvoidrun(){

//获取当前线程名称

StringcurrentThreadName=Thread.currentThread().getName();

//线程执行内容

for(inti=0;i<5;i++){

System.out.println(currentThreadName+"isrunning,count"+i);

try{

//休眠100毫秒

Thread.sleep(100);

}catch(InterruptedExceptione){

//处理中断异常

System.out.println(currentThreadName+"wasinterrupted");

}

}

}

}

//创建线程实例

MyThreadthread1=newMyThread("Thread-1");

MyThreadthread2=newMyThread("Thread-2");

//启动线程

thread1.start();

thread2.start();

```

2.实现Runnable接口

-实现`Runnable`接口是实现线程的另一种方式,也是推荐的方式。通过实现`Runnable`接口,可以将线程的执行逻辑与线程本身分离,提高代码的可复用性。

-以下是实现`Runnable`接口创建线程的步骤:

1.定义一个类,实现`Runnable`接口,并重写`run()`方法。

2.创建该类的实例,将其实例传递给`Thread`类的构造方法。

3.创建`Thread`类的实例,并将`Runnable`实例作为参数传递给构造方法,调用`start()`方法启动线程。

-示例代码:

```java

classMyRunnableimplementsRunnable{

privateStringname;

//构造方法

publicMyRunnable(Stringname){

=name;

}

//重写run()方法

@Override

publicvoidrun(){

//获取当前线程名称

StringcurrentThreadName=Thread.currentThread().getName();

//线程执行内容

for(inti=0;i<5;i++){

System.out.println(currentThreadName+"isrunning,count"+i);

try{

//休眠100毫秒

Thread.sleep(100);

}catch(InterruptedExceptione){

//处理中断异常

System.out.println(currentThreadName+"wasinterrupted");

}

}

}

}

//创建Runnable实例

MyRunnablerunnable1=newMyRunnable("Runnable-1");

MyRunnablerunnable2=newMyRunnable("Runnable-2");

//创建线程实例,并将Runnable实例传递给构造方法

Threadthread1=newThread(runnable1);

Threadthread2=newThread(runnable2);

//启动线程

thread1.start();

thread2.start();

```

3.使用Callable和Future(带返回值)

-`Callable`接口和`Future`类是Java5引入的,用于实现有返回值的线程。

-`Callable`接口类似于`Runnable`接口,但它可以返回一个结果,并且可以抛出异常。

-`Future`接口表示异步计算的结果,可以通过它来查询计算是否完成,以及获取计算结果。

-以下是使用`Callable`和`Future`创建线程的步骤:

1.定义一个类,实现`Callable`接口,并重写`call()`方法。

2.创建该类的实例,将其实例传递给`ExecutorService`的`submit()`方法。

3.`submit()`方法返回一个`Future`实例,可以通过该实例获取线程的执行结果。

-示例代码:

```java

importjava.util.concurrent.Callable;

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

importjava.util.concurrent.Future;

importjava.util.concurrent.ExecutionException;

classMyCallableimplementsCallable<Integer>{

privateStringname;

//构造方法

publicMyCallable(Stringname){

=name;

}

//重写call()方法

@Override

publicIntegercall()throwsException{

//获取当前线程名称

StringcurrentThreadName=Thread.currentThread().getName();

//线程执行内容

System.out.println(currentThreadName+"isrunning");

//模拟计算过程

intresult=0;

for(inti=0;i<5;i++){

result+=i;

System.out.println(currentThreadName+"iscalculating,currentresult"+result);

//休眠100毫秒

Thread.sleep(100);

}

returnresult;

}

}

publicclassCallableExample{

publicstaticvoidmain(String[]args){

//创建线程池

ExecutorServiceexecutor=Executors.newSingleThreadExecutor();

//创建Callable实例

MyCallablecallable1=newMyCallable("Callable-1");

MyCallablecallable2=newMyCallable("Callable-2");

//提交任务并获取Future实例

Future<Integer>future1=executor.submit(callable1);

Future<Integer>future2=executor.submit(callable2);

try{

//获取线程执行结果

Integerresult1=future1.get();

Integerresult2=future2.get();

//输出结果

System.out.println("ResultofCallable-1:"+result1);

System.out.println("ResultofCallable-2:"+result2);

}catch(InterruptedExceptione){

//处理中断异常

System.out.println("Theexecutionofthetaskwasinterrupted");

}catch(ExecutionExceptione){

//处理计算异常

System.out.println("Anexceptionoccurredduringthetaskexecution");

}finally{

//关闭线程池

executor.shutdown();

}

}

}

```

(三)线程生命周期管理

1.暂停与恢复

-`Thread.sleep(longmillis)`:使当前线程休眠指定的时间(以毫秒为单位)。在休眠期间,线程会释放CPU资源,但仍然保留其占用的其他资源。休眠结束后,线程会重新进入可运行状态,等待CPU调度。

-示例代码:

```java

try{

//休眠1000毫秒

Thread.sleep(1000);

}catch(InterruptedExceptione){

//处理中断异常

System.out.println("Threadwasinterruptedduringsleep");

}

```

-`Thread.join()`:使当前线程等待指定线程执行完毕。调用`join()`方法的线程会进入阻塞状态,直到目标线程终止。

-示例代码:

```java

Threadthread1=newThread(()->{

for(inti=0;i<3;i++){

System.out.println(Thread.currentThread().getName()+"isrunning,count"+i);

try{

Thread.sleep(500);

}catch(InterruptedExceptione){

System.out.println(Thread.currentThread().getName()+"wasinterrupted");

}

}

});

Threadthread2=newThread(()->{

for(inti=0;i<3;i++){

System.out.println(Thread.currentThread().getName()+"isrunning,count"+i);

try{

Thread.sleep(500);

}catch(InterruptedExceptione){

System.out.println(Thread.currentThread().getName()+"wasinterrupted");

}

}

});

thread1.start();

thread2.start();

try{

//等待thread1执行完毕

thread1.join();

//等待thread2执行完毕

thread2.join();

}catch(InterruptedExceptione){

System.out.println("Themainthreadwasinterrupted");

}

System.out.println("Mainthreadisfinished");

```

-`Thread.yield()`:使当前线程放弃CPU执行权,让其他同优先级的线程有机会执行。`yield()`方法并不会使线程进入阻塞状态,只是当前线程主动让出CPU,并不一定会立即被调度。

-示例代码:

```java

for(inti=0;i<5;i++){

System.out.println(Thread.currentThread().getName()+"isrunning,count"+i);

Thread.yield();

}

```

2.优先级设置

-Java线程的优先级范围是1到10,默认优先级为5。优先级较高的线程在可运行状态时更有可能被CPU调度。

-`setPriority(intpriority)`:设置线程的优先级。优先级值范围为1到10,数值越高,优先级越高。

-示例代码:

```java

Threadthread=newThread(()->{

System.out.println(Thread.currentThread().getName()+"isrunning");

});

//设置线程优先级为10

thread.setPriority(Thread.MAX_PRIORITY);

thread.start();

```

-`getPriority()`:获取线程的当前优先级。

-示例代码:

```java

Threadthread=newThread(()->{

System.out.println(Thread.currentThread().getName()+"isrunning");

});

//获取线程优先级

intpriority=thread.getPriority();

System.out.println(Thread.currentThread().getName()+"haspriority"+priority);

```

3.中断管理

-`interrupt()`:中断一个线程。中断操作不会立即终止线程,而是设置一个中断标志,线程可以通过检查中断标志来响应中断。

-`isInterrupted()`:检查当前线程是否被中断。该方法会清除中断标志,即如果线程被中断,调用`isInterrupted()`后中断标志会被清除。

-示例代码:

```java

Threadthread=newThread(()->{

while(!Thread.currentThread().isInterrupted()){

System.out.println(Thread.currentThread().getName()+"isrunning");

try{

Thread.sleep(1000);

}catch(InterruptedExceptione){

//如果线程被中断,捕获InterruptedException

Thread.currentThread().interrupt();//重新设置中断标志

System.out.println(Thread.currentThread().getName()+"wasinterrupted");

}

}

});

thread.start();

try{

Thread.sleep(2000);

}catch(InterruptedExceptione){

System.out.println("Mainthreadwasinterrupted");

}

//中断thread

errupt();

```

-`Terrupted()`:检查当前线程是否被中断,并清除中断标志。该方法会检查当前线程的中断状态,如果线程被中断,则清除中断标志,并返回`true`;否则返回`false`。

-示例代码:

```java

Threadthread=newThread(()->{

while(!Terrupted()){

System.out.println(Thread.currentThread().getName()+"isrunning");

try{

Thread.sleep(1000);

}catch(InterruptedExceptione){

//如果线程被中断,捕获InterruptedException

System.out.println(Thread.currentThread().getName()+"wasinterrupted");

}

}

});

thread.start();

try{

Thread.sleep(2000);

}catch(InterruptedExceptione){

System.out.println("Mainthreadwasinterrupted");

}

//中断thread

errupt();

```

---

一、概述

Java多线程编程是实现并发处理的关键技术,能够显著提高应用程序的性能和响应速度。本手册旨在为开发者提供一套系统性的指导,涵盖多线程基础、常用类库、线程安全、性能优化等方面。通过学习本手册,开发者能够掌握Java多线程编程的核心概念和实践方法。

---

二、多线程基础

(一)线程的基本概念

1.线程与进程的区别

-进程:资源分配的基本单位,包含多个线程。

-线程:CPU调度的基本单位,共享进程资源。

2.线程状态

-新建(New):线程创建后未启动。

-运行(Running):CPU正在执行线程。

-就绪(Ready):线程已准备就绪,等待CPU调度。

-阻塞(Blocked):线程因等待资源或事件而暂停。

-死亡(Terminated):线程执行完毕或异常终止。

(二)线程创建与启动

1.继承Thread类

```java

classMyThreadextendsThread{

publicvoidrun(){

//线程执行内容

}

}

MyThreadthread=newMyThread();

thread.start();

```

2.实现Runnable接口(推荐)

```java

classMyRunnableimplementsRunnable{

publicvoidrun(){

//线程执行内容

}

}

Threadthread=newThread(newMyRunnable());

thread.start();

```

3.使用Callable和Future(带返回值)

```java

classMyCallableimplementsCallable<Integer>{

publicIntegercall()throwsException{

return42;

}

}

ExecutorServiceexecutor=Executors.newSingleThreadExecutor();

Future<Integer>future=executor.submit(newMyCallable());

Integerresult=future.get();

```

(三)线程生命周期管理

1.暂停与恢复

-`Thread.sleep(longmillis)`:线程休眠指定时间。

-`Thread.join()`:当前线程等待目标线程执行完毕。

2.优先级设置

-`setPriority(intpriority)`:设置线程优先级(1-10)。

-`getPriority()`:获取线程优先级。

3.中断管理

-`interrupt()`:中断线程。

-`isInterrupted()`:检查线程是否被中断。

-`Terrupted()`:清除中断状态。

---

三、线程同步机制

(一)同步方法与同步块

1.同步方法

-使用`synchronized`关键字修饰。

```java

synchronizedvoidsynchronizedMethod(){

//代码块

}

```

2.同步块

-作用于代码块或对象。

```java

Objectlock=newObject();

synchronized(lock){

//代码块

}

```

(二)锁机制

1.ReentrantLock

-可中断锁、可公平锁。

```java

ReentrantLocklock=newReentrantLock();

lock.lock();

try{

//代码块

}finally{

lock.unlock();

}

```

2.ReadWriteLock

-读写分离锁,提高并发性能。

```java

ReadWriteLockrwLock=newReentrantReadWriteLock();

rwLock.readLock().lock();

try{

//读取操作

}finally{

rwLock.readLock().unlock();

}

```

(三)原子类

1.基本类型原子类

-`AtomicInteger`,`AtomicLong`等。

```java

AtomicIntegercount=newAtomicInteger(0);

count.incrementAndGet();//count=1

```

2.引用类型原子类

-`AtomicReference`,用于引用类型。

---

四、线程池与任务调度

(一)线程池使用

1.创建线程池

-`Executors.newFixedThreadPool(intnThreads)`:固定大小线程池。

-`Executors.newCachedThreadPool()`:可缓存线程池。

```java

ExecutorServicepool=Executors.newFixedThreadPool(5);

pool.submit(()->System.out.println("Taskexecuted"));

pool.shutdown();

```

2.线程池参数配置

-核心线程数、最大线程数、空闲存活时间、工作队列。

(二)任务调度

1.ScheduledExecutorService

-支持定时任务。

```java

ScheduledExecutorServicescheduler=Executors.newScheduledThreadPool(1);

scheduler.scheduleAtFixedRate(()->System.out.println("Timertask"),0,1,TimeUnit.SECONDS);

```

---

五、线程安全与并发容器

(一)线程安全集合

1.常用线程安全集合

-`ConcurrentHashMap`,`CopyOnWriteArrayList`。

```java

ConcurrentHashMap<String,Integer>map=newConcurrentHashMap<>();

map.put("key",1);

```

(二)并发工具类

1.CountDownLatch

-等待多个线程执行完毕。

```java

CountDownLatchlatch=newCountDownLatch(3);

for(inti=0;i<3;i++){

newThread(()->{

//任务执行

latch.countDown();

}).start();

}

latch.await();

```

2.CyclicBarrier

-多线程互相等待。

```java

CyclicBarrierbarrier=newCyclicBarrier(3,()->System.out.println("Allthreadsreached"));

```

---

六、性能优化建议

1.选择合适的线程池规模

-根据CPU核心数和工作负载调整。

2.避免过度同步

-减少同步块范围,使用原子类替代。

3.使用并发API

-偏向锁(`ReentrantLock`)、并发集合。

---

七、常见问题排查

1.死锁排查

-使用`jstack`分析线程堆栈。

2.资源竞争优化

-减少锁粒度,使用`ReadWriteLock`。

---

八、总结

Java多线程编程涉及多个层面,从基础线程管理到高级并发控制,需要开发者结合实际场景灵活应用。本手册提供了一套完整的实践指南,开发者可通过不断练习和优化,提升并发程序的性能和稳定性。

---

二、多线程基础

(一)线程的基本概念

1.线程与进程的区别

-进程:可以理解为程序的一次执行过程,是系统进行资源分配和调度的基本单位。一个进程可以包含多个线程,这些线程共享进程所拥有的资源,如内存空间、文件句柄等。进程之间通常相互隔离,资源独立。

-线程:是CPU调度的基本单位,比进程更轻量级。线程本身不拥有资源,而是共享所属进程的资源。一个进程至少包含一个线程,即主线程。线程的创建、销毁和切换比进程更快,因此使用多线程可以实现更高效的并发处理。

2.线程状态

-新建(New):当使用`Thread`类或`Runnable`接口创建一个新的线程对象后,该线程就处于新建状态。此时线程尚未被CPU分配执行资源,也没有开始执行。

-可运行(Runnable):当调用线程的`start()`方法后,线程的状态从新建变为可运行。此时线程已经准备好执行,但尚未获得CPU的执行权,处于就绪队列中,等待CPU调度。

-阻塞(Blocked):线程在执行过程中可能会遇到需要等待的情况,例如等待I/O操作完成、等待获取锁等。当线程进入这些等待状态时,其状态变为阻塞。线程阻塞时不会占用CPU资源,直到阻塞条件解除。

-等待(Waiting):线程可以显式地进入等待状态,例如调用`Object.wait()`方法。等待状态的线程需要其他线程调用其`notify()`或`notifyAll()`方法才能退出等待状态。

-时间等待(TimedWaiting):线程可以进入时间等待状态,例如调用`Thread.sleep(longmillis)`方法或`Object.wait(longtimeout)`方法。时间等待状态的线程会在指定的时间后自动退出等待状态。

-终止(Terminated):当线程的`run()`方法执行完毕或线程被强制终止时,线程的状态变为终止。终止状态的线程无法再被激活。

(二)线程创建与启动

1.继承Thread类

-继承`Thread`类是实现线程的一种方式。通过继承`Thread`类,可以创建一个自定义的线程类,并在该类中重写`run()`方法来定义线程的执行逻辑。

-以下是继承`Thread`类创建线程的步骤:

1.定义一个类,继承自`Thread`类。

2.在该类中重写`run()`方法,定义线程的执行内容。

3.创建该类的实例,调用实例的`start()`方法启动线程。

-示例代码:

```java

classMyThreadextendsThread{

//构造方法

publicMyThread(Stringname){

super(name);//设置线程名称

}

//重写run()方法

@Override

publicvoidrun(){

//获取当前线程名称

StringcurrentThreadName=Thread.currentThread().getName();

//线程执行内容

for(inti=0;i<5;i++){

System.out.println(currentThreadName+"isrunning,count"+i);

try{

//休眠100毫秒

Thread.sleep(100);

}catch(InterruptedExceptione){

//处理中断异常

System.out.println(currentThreadName+"wasinterrupted");

}

}

}

}

//创建线程实例

MyThreadthread1=newMyThread("Thread-1");

MyThreadthread2=newMyThread("Thread-2");

//启动线程

thread1.start();

thread2.start();

```

2.实现Runnable接口

-实现`Runnable`接口是实现线程的另一种方式,也是推荐的方式。通过实现`Runnable`接口,可以将线程的执行逻辑与线程本身分离,提高代码的可复用性。

-以下是实现`Runnable`接口创建线程的步骤:

1.定义一个类,实现`Runnable`接口,并重写`run()`方法。

2.创建该类的实例,将其实例传递给`Thread`类的构造方法。

3.创建`Thread`类的实例,并将`Runnable`实例作为参数传递给构造方法,调用`start()`方法启动线程。

-示例代码:

```java

classMyRunnableimplementsRunnable{

privateStringname;

//构造方法

publicMyRunnable(Stringname){

=name;

}

//重写run()方法

@Override

publicvoidrun(){

//获取当前线程名称

StringcurrentThreadName=Thread.currentThread().getName();

//线程执行内容

for(inti=0;i<5;i++){

System.out.println(currentThreadName+"isrunning,count"+i);

try{

//休眠100毫秒

Thread.sleep(100);

}catch(InterruptedExceptione){

//处理中断异常

System.out.println(currentThreadName+"wasinterrupted");

}

}

}

}

//创建Runnable实例

MyRunnablerunnable1=newMyRunnable("Runnable-1");

MyRunnablerunnable2=newMyRunnable("Runnable-2");

//创建线程实例,并将Runnable实例传递给构造方法

Threadthread1=newThread(runnable1);

Threadthread2=newThread(runnable2);

//启动线程

thread1.start();

thread2.start();

```

3.使用Callable和Future(带返回值)

-`Callable`接口和`Future`类是Java5引入的,用于实现有返回值的线程。

-`Callable`接口类似于`Runnable`接口,但它可以返回一个结果,并且可以抛出异常。

-`Future`接口表示异步计算的结果,可以通过它来查询计算是否完成,以及获取计算结果。

-以下是使用`Callable`和`Future`创建线程的步骤:

1.定义一个类,实现`Callable`接口,并重写`call()`方法。

2.创建该类的实例,将其实例传递给`ExecutorService`的`submit()`方法。

3.`submit()`方法返回一个`Future`实例,可以通过该实例获取线程的执行结果。

-示例代码:

```java

importjava.util.concurrent.Callable;

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

importjava.util.concurrent.Future;

importjava.util.concurrent.ExecutionException;

classMyCallableimplementsCallable<Integer>{

privateStringname;

//构造方法

publicMyCallable(Stringname){

=name;

}

//重写call()方法

@Override

publicIntegercall()throwsException{

//获取当前线程名称

StringcurrentThreadName=Thread.currentThread().getName();

//线程执行内容

System.out.println(currentThreadName+"isrunning");

//模拟计算过程

intresult=0;

for(inti=0;i<5;i++){

result+=i;

System.out.println(currentThreadName+"iscalculating,currentresult"+result);

//休眠100毫秒

Thread.sleep(100);

}

returnresult;

}

}

publicclassCallableExample{

publicstaticvoidmain(String[]args){

//创建线程池

ExecutorServiceexecutor=Executors.newSingleThreadExecutor();

//创建Callable实例

MyCallablecallable1=newMyCallable("Callable-1");

MyCallablecallable2=newMyCallable("Callable-2");

//提交任务并获取Future实例

Future<Integer>future1=executor.submit(callable1);

Future<Integer>future2=executor.submit(callable2);

try{

//获取线程执行结果

Integerresult1=future1.get();

Integerresult2=future2.get();

//输出结果

System.out.println("ResultofCallable-1:"+result1);

System.out.println("ResultofCallable-2:"+result2);

}catch(InterruptedExceptione){

//处理中断异常

System.out.println("Theexecutionofthetaskwasinterrupted");

}catch(ExecutionExceptione){

//处理计算异常

System.out.println("Anexceptionoccurredduringthetaskexecution");

}finally{

//关闭线程池

executor.shutdown();

}

}

}

```

(三)线程生命周期管理

1.暂停与恢复

-`Thread.sleep(longmillis)`:使当前线程休眠指定的时间(以毫秒为单位)。在休眠期间,线程会释放CPU资源,但仍然保留其占用的其他资源。休眠结束后,线程会重新进入可运行状态,等待CPU调度。

-示例代码:

```java

try{

//休眠1000毫秒

Thread.sleep(1000);

}catch(InterruptedExceptione){

//处理中断异常

System.out.println("Threadwasinterruptedduringsleep");

}

```

-`Thread.join()`:使当前线程等待指定线程执行完毕。调用`join()`方法的线程会进入阻塞状态,直到目标线程终止。

-示例代码:

```java

Threadthread1=newThread(()->{

for(inti=0;i<3;i++){

System.out.println(Thread.currentThread().getName()+"isrunning,count"+i);

try{

Thread.sleep(500);

}catch(InterruptedExceptione){

System.out.println(Thread.currentThread().getName()+"wasinterrupted");

}

}

});

Threadthread2=newThread(()->{

for(inti=0;i<3;i++){

System.out.println(Thread.currentThread().getName()+"isrunning,count"+i);

try{

Thread.sleep(500);

}catch(InterruptedExceptione){

System.out.println(Thread.currentThread().getName()+"wasinterrupted");

}

}

});

thread1.start();

thread2.start();

try{

//等待thread1执行完毕

thread1.join();

//等待thread2执行完毕

thread

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论