本文共 6408 字,大约阅读时间需要 21 分钟。
线程通信是多线程程序中实现线程间相互调度和信息传递的重要机制。在Java中,线程通信主要通过锁、条件、可重入锁等机制实现。以下将从多个角度探讨线程通信的实现方法及其应用案例。
线程通信的核心机制包括等待和唤醒。wait()方法使得线程进入阻塞状态,直到被另一个线程调用notify()或notifyAll()唤醒。notify()方法会唤醒等待队列中优先级最高的线程,而notifyAll()则会唤醒所有等待的线程。
在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(); } }} 在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(); } } } }} 如果直接继承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(); } } } }} 消费者-生产者问题是多线程编程中的经典问题,涉及多个线程之间的协调。以下是一个简单的柜台类实现:
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(); } } }} 生产者线程负责在柜台中添加物品,以下是一个生产者线程的实现:
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(); } } }} 消费者线程负责从柜台中取走物品,以下是一个消费者线程的实现:
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(); } } }} 以下是一个使用上述组件的测试类:
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(); }} 在JDK8中,FutureTask和ExecutorService提供了更简便的线程创建方式。以下是一个使用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(); } }} 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/