行业知识
Java多线程算法总结
2026-10-29 11:01:17
来源:互联网转载
1. 标题三个线程同时运行,依次打印ABC,一共打印10次
index.php/tags-41973.html" >���法代码如下:
public class ThreadTest { private Object oa = new Object(); private Object ob = new Object(); private Object oc = new Object(); private static final String TAG = "ThreadTest"; private Runnable a = new Runnable() { @Override public void run() { int count = 10; while (count > 0) { synchronized (oc) { //首先需要等待上个线程执行打印后,才能执行自己线程的打印任务。因此要获取到上个对象锁,这里是oc,并且执行oc.wait()方法 //这样一旦在C线程中,oc执行了notify()方法后,才能按顺序让A线程继续执行 synchronized (oa) { // 为了唤醒下一个B线程,执行oa.notify()方法,那么就需要对oa加锁 Log.i(TAG, "A"); count --; oa.notify(); } try { oc.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; private Runnable b = new Runnable() { @Override public void run() { int count = 10; while (count > 0) { synchronized (oa) { synchronized (ob) { Log.i(TAG, "B"); count --; ob.notify(); } try { oa.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; private Runnable c = new Runnable() { @Override public void run() { int count = 10; while (count > 0) { synchronized (ob) { synchronized (oc) { Log.i(TAG, "C"); count --; oc.notify(); } try { ob.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; public void startThread() { Thread at = new Thread(a); Thread bt = new Thread(b); Thread ct = new Thread(c); try { at.start(); Thread.sleep(100); //保证第一次循环是ABC的顺序 bt.start(); Thread.sleep(100); ct.start(); } catch (InterruptedException e) { e.printStackTrace(); } }} 也可以把重复的Runnable抽象成一个,如下:
private static class PrintRunnable implements Runnable { Object prev; Object current; String name; PrintRunnable(String name, Object prev, Object current) { this.name = name; this.prev = prev; this.current = current; } @Override public void run() { int count = 10; while (count > 0) { synchronized (prev) { synchronized (current) { Log.i(TAG, name); count --; current.notify(); } try { prev.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public void startThread2() { Thread ta = new Thread(new PrintRunnable("A", oc, oa)); Thread tb = new Thread(new PrintRunnable("B", oa, ob)); Thread tc = new Thread(new PrintRunnable("C", ob, oc)); try { ta.start(); Thread.sleep(100); tb.start(); Thread.sleep(100); tc.start(); } catch (InterruptedException e) { e.printStackTrace(); } } wait()会释放对象锁;notify()是起到唤醒等待对象锁的线程的作用,并不会马上释放锁,但是一旦同步代码块执行完毕后,就会释放对象锁。
2.生产者-消费者问题
代码如下:
/** * 生产者消费者问题 */ private static final int MAX_COUNT = 10; List product = new LinkedList(); // 生产者 private Runnable build = new Runnable() { @Override public void run() { while (true) { synchronized (product) { while (product.size() >= MAX_COUNT) { // 如果商品已经达到最大存储量,则暂时不生产 try { Log.i(TAG, Thread.currentThread().getName() + " 仓库已满"); product.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } product.add("商品"); Log.i(TAG, Thread.currentThread().getName() + " 生产一个商品,当前商品存储量:" + product.size()); product.notifyAll(); // 唤醒等待商品的消费者 } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } }; // 消费者 private Runnable consume = new Runnable() { @Override public void run() { while (true) { synchronized (product) { while (product.isEmpty()) { try { Log.i(TAG, Thread.currentThread().getName() + " 仓库已空"); product.wait(); // 没有商品消费,等待生产 } catch (InterruptedException e) { e.printStackTrace(); } } product.remove(0); Log.i(TAG, Thread.currentThread().getName() + " 消费一个商品,当前商品存储量:" + product.size()); product.notifyAll(); // 通知等待生产的生产者 } try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } } } }; public void startThread3() { Thread buildThread1 = new Thread(build); Thread buildThread2 = new Thread(build); Thread consumeThread1 = new Thread(consume); Thread consumeThread2 = new Thread(consume); Thread consumeThread3 = new Thread(consume); buildThread1.start(); consumeThread1.start(); buildThread2.start(); consumeThread2.start(); consumeThread3.start(); } 打印如下:
上一篇:e3怎么架设服务器?
下一篇:怎么使用服务器的公网IP?