博客
关于我
线程(下)--线程通信&&消费者问题
阅读量:285 次
发布时间:2019-03-03

本文共 6408 字,大约阅读时间需要 21 分钟。

线程通信是多线程程序中实现线程间相互调度和信息传递的重要机制。在Java中,线程通信主要通过锁、条件、可重入锁等机制实现。以下将从多个角度探讨线程通信的实现方法及其应用案例。

1. 线程通信的基本机制

线程通信的核心机制包括等待和唤醒。wait()方法使得线程进入阻塞状态,直到被另一个线程调用notify()notifyAll()唤醒。notify()方法会唤醒等待队列中优先级最高的线程,而notifyAll()则会唤醒所有等待的线程。

2. 实现Runnable接口的线程通信

在Java中,Runnable接口是一种轻量级的线程执行方式。以下是一个实现Runnable接口的线程通信示例:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintNum implements Runnable {
private static int num = 0;
private static Lock lock = new ReentrantLock();
private static Condition con = lock.newCondition();
@Override
public void run() {
while (true) {
lock.lock();
con.signal();
num++;
if (num <= 100) {
System.out.println(Thread.currentThread().getName() + ":" + num);
} else {
lock.unlock();
break;
}
con.await();
lock.unlock();
}
}
}

3. 使用synchronize修饰同步代码块

Runnable接口的实现中,可以通过synchronize修饰方法或代码块来实现线程同步。以下是一个使用synchronize修饰同步代码块的示例:

public class PrintNum implements Runnable {
private static int num = 0;
@Override
public void run() {
while (true) {
synchronized (this) {
this.notify();
if (num <= 100) {
System.out.println(Thread.currentThread().getName() + ":" + num);
num++;
} else {
break;
}
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

4. 继承Thread类的线程通信

如果直接继承Thread类,可以通过Object对象作为锁,实现线程通信。以下是一个继承Thread类的线程通信示例:

public class PrintNum extends Thread {
private static int num = 0;
private static Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (obj) {
obj.notify();
if (num <= 100) {
System.out.println(Thread.currentThread().getName() + ":" + num);
num++;
} else {
break;
}
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

5. 消费者-生产者问题

消费者-生产者问题是多线程编程中的经典问题,涉及多个线程之间的协调。以下是一个简单的柜台类实现:

public class Counter {
private int num = 0;
public synchronized void add() {
if (num == 0) {
num++;
System.out.println("生产一个");
this.notify();
} else {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void sub() {
if (num == 1) {
num--;
System.out.println("消费一个");
this.notify();
} else {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

6. 生产者线程

生产者线程负责在柜台中添加物品,以下是一个生产者线程的实现:

public class Productor extends Thread {
private Counter c;
public Productor(Counter c) {
this.c = c;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
c.add();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

7. 消费者线程

消费者线程负责从柜台中取走物品,以下是一个消费者线程的实现:

public class Customer extends Thread {
private Counter c;
public Customer(Counter c) {
this.c = c;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
c.sub();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

8. 测试类

以下是一个使用上述组件的测试类:

public class Test {
public static void main(String[] args) {
Counter c = new Counter();
Productor p = new Productor(c);
Customer ct = new Customer(c);
p.start();
ct.start();
}
}

9. JDK8 以后的线程创建方法

在JDK8中,FutureTaskExecutorService提供了更简便的线程创建方式。以下是一个使用FutureTask的示例:

import java.util.concurrent.Callable;
public class SumNumThread implements Callable {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
}
public class Test {
public static void main(String[] args) {
SumNumThread sum = new SumNumThread();
FutureTask futureTask = new FutureTask(sum);
Thread t = new Thread(futureTask);
t.start();
try {
Integer val = futureTask.get();
System.out.println(val);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

10. 使用ExecutorService创建线程池

ExecutorService提供了线程池的创建方式,可以根据需要配置线程池的大小。以下是一个使用ExecutorService的示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SumNumThread implements Callable {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName());
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
}
public class Test {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
SumNumThread sumNumThread = new SumNumThread();
executorService.submit(sumNumThread);
executorService.submit(sumNumThread);
executorService.submit(sumNumThread);
executorService.submit(sumNumThread);
executorService.submit(sumNumThread);
Future f = executorService.submit(sumNumThread);
try {
System.out.println(f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executorService.shutdown();
}
}

通过以上方法,可以实现线程间的通信与协调,确保多线程程序的正确执行。

转载地址:http://noul.baihongyu.com/

你可能感兴趣的文章
Objective-C实现KadaneAlgo计算给定数组的最大连续子数组和算法(附完整源码)
查看>>
Objective-C实现karatsuba大数相乘算法(附完整源码)
查看>>
Objective-C实现KMP搜索算法(附完整源码)
查看>>
Objective-C实现Knapsack problem背包问题算法(附完整源码)
查看>>
Objective-C实现knapsack背包问题算法(附完整源码)
查看>>
Objective-C实现knapsack背包问题算法(附完整源码)
查看>>
Objective-C实现knight tour骑士之旅算法(附完整源码)
查看>>
Objective-C实现knight Tour骑士之旅算法(附完整源码)
查看>>
Objective-C实现KNN算法(附完整源码)
查看>>
Objective-C实现koch snowflake科赫雪花算法(附完整源码)
查看>>
Objective-C实现KPCA(附完整源码)
查看>>
Objective-C实现KruskalMST最小生成树的算法(附完整源码)
查看>>
Objective-C实现kth order statistick阶统计量算法(附完整源码)
查看>>
Objective-C实现Lempel-Ziv压缩算法(附完整源码)
查看>>
Objective-C实现logistic regression逻辑回归算法(附完整源码)
查看>>
Objective-C实现LongestIncreasingSubsequence最长递增子序列算法(附完整源码)
查看>>
Objective-C实现Lower-Upper Decomposition上下分解算法(附完整源码)
查看>>
Objective-C实现lowest common ancestor最低共同祖先算法(附完整源码)
查看>>
Objective-C实现LRU 缓存算法(附完整源码)
查看>>
Objective-C实现LRU缓存(附完整源码)
查看>>