汇总

  • 案例一
  • 案例二
  • 案例三
  • 案例四
  • 案例五
  • 案例六
  • 案例七

案例一

实现一个容器,提供两个方法,add(),count() 写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束。
本案例我通过闭锁(也叫门栓锁)实现,实现如下:

package day_12_28.zuoye;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;/*** @author soberw* @Classname AddAndCount* @Description 实现一个容器,提供两个方法,add,count 写两个线程,* 线程1添加10个元素到容器中,线程2实现监控元素的个数,* 当个数到5个时,线程2给出提示并结束。* @Date 2021-12-28 10:45*/
public class AddAndCount {CountDownLatch cdl = new CountDownLatch(1);List<String> list = new ArrayList<>();public static void main(String[] args) {var aac = new AddAndCount();new Thread(aac::add, "A").start();new Thread(aac::count, "B").start();}void add() {for (int i = 0; i < 10; i++) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}String item = String.format("%s - %d", "item", i);list.add(item);System.out.println(Thread.currentThread().getName() + ":" + item);if (i == 4) {cdl.countDown();}}}void count() {try {cdl.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("程序结束...");System.exit(0);}
}

案例二

编写程序模拟死锁。
死锁,简单来说就是两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
下面我就模拟这一状态:

package day_12_28.zuoye;/*** @author soberw* @Classname Deadlock* @Description 编写程序模拟死锁* @Date 2021-12-28 10:59*/
public class Deadlock {private final Object o1 = new Object();private final Object o2 = new Object();public static void main(String[] args) {Deadlock d = new Deadlock();new Thread(d::m1).start();new Thread(d::m2).start();}void m1(){System.out.println(Thread.currentThread().getName() + "启动等待...");synchronized(o1){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized(o2){System.out.println("哈哈..");}}}void m2(){System.out.println(Thread.currentThread().getName() + "启动等待...");synchronized(o2){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized(o1){System.out.println("哈哈..");}}}}

案例三

编写程序,实现三个线程,运行输出 A1 B2 C3 A4 B5 C6 ……
我这里用了两种方式去实现:
方式一:
用公平锁:

package day_12_28.zuoye;import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;/*** @author soberw* @Classname TurnNumber* @Description 编写程序,实现三个线程,运行输出 A1 B2 C3 A4 B5 C6 …..  用公平锁* @Date 2021-12-28 14:09*/
public class TurnNumber {AtomicInteger num = new AtomicInteger(0);private final ReentrantLock rl = new ReentrantLock(true);public void show() {for (; ; ) {rl.lock();try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}String tn = Thread.currentThread().getName();int i = num.incrementAndGet();String s = String.format("%s%d", tn, i);System.out.print(s + "  ");if ("C".equals(tn)) {System.out.println();}rl.unlock();}}public static void main(String[] args) throws InterruptedException {TurnNumber tn = new TurnNumber();Thread a = new Thread(tn::show, "A");Thread b = new Thread(tn::show, "B");Thread c = new Thread(tn::show, "C");a.setPriority(Thread.MAX_PRIORITY);a.start();b.setPriority(Thread.NORM_PRIORITY);b.start();c.setPriority(Thread.MIN_PRIORITY);c.start();}
}


方式二:
用join() 方法

package day_12_28.zuoye;import java.util.concurrent.atomic.AtomicInteger;/*** @author soberw* @Classname TurnNumber* @Description 编写程序,实现三个线程,运行输出 A1 B2 C3 A4 B5 C6 …..  第二种写法,用join()* @Date 2021-12-28 14:09*/
public class TurnNumber2 {AtomicInteger num = new AtomicInteger(0);public void show() {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}String tn = Thread.currentThread().getName();int i = num.incrementAndGet();String s = String.format("%s%d", tn, i);System.out.print(s + "  ");if ("C".equals(tn)) {System.out.println();}}public static void main(String[] args) throws InterruptedException {TurnNumber2 tn = new TurnNumber2();while (true) {Thread a = new Thread(tn::show, "A");Thread b = new Thread(tn::show, "B");Thread c = new Thread(tn::show, "C");a.setPriority(Thread.MAX_PRIORITY);a.start();a.join();b.setPriority(Thread.NORM_PRIORITY);b.start();b.join();c.setPriority(Thread.MIN_PRIORITY);c.start();c.join();}}
}

案例四

创建五个线程并进入等待状态,等两秒后主线程开始并释放全部线程,最后主线程结束

本案例我用的是wait() 与notifyAll()组合形式;

package day_12_27;import java.util.concurrent.TimeUnit;/*** @author soberw* @Classname WaitAndNotify* @Description  创建五个线程并进入等待状态,等两秒后主线程开始并释放全部线程,最后主线程结束* @Date 2021-12-27 15:47*/
public class WaitAndNotify {public static void main(String[] args) {Object co = new Object();for (int i = 0; i < 5; i++) {MyThread t = new MyThread("Thread" + i, co);t.start();}try {TimeUnit.SECONDS.sleep(2);System.out.println("-----Main Thread notify-----");synchronized (co) {//co.notify();co.notifyAll();}TimeUnit.SECONDS.sleep(2);System.out.println("Main Thread is end.");} catch (InterruptedException e) {e.printStackTrace();}}static class MyThread extends Thread {private String name;private Object co;public MyThread(String name, Object o) {this.name = name;this.co = o;}@Overridepublic void run() {System.out.println(name + " is waiting.");try {synchronized (co) {co.wait();}System.out.println(name + " has been notified.");} catch (InterruptedException e) {e.printStackTrace();}}}
}

案例五

用五个线程实现,求123456789 之间放±和100的表达式,如果一个线程求出结果,立即告诉其它停止。

这里我用到了AtomicBoolean原子类来保证数据的原子性:

package day_12_27.zuoye;import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** @author soberw* @Classname Number100* @Description 用五个线程实现,求123456789 之间放+-和100的表达式,如果一个线程求出结果,立即告诉其它停止。* @Date 2021-12-27 21:14*/
public class Number100 {//原子类,保证原子性AtomicBoolean ab = new AtomicBoolean(true);public void show() {String[] ss = {"", "+", "-"};StringBuilder sbu = new StringBuilder();sbu.append("1");Random random = new Random();while (ab.get()) {for (int i = 2; i < 9; i++) {sbu.append(ss[random.nextInt(3)]);sbu.append(i);}Pattern p = Pattern.compile("[0-9]+|-[0-9]+");Matcher m = p.matcher(sbu.toString());int sum = 0;while (m.find()) {sum += Integer.parseInt(m.group());}if (sum == 100) {ab.set(false);System.out.println(Thread.currentThread().getName() + ":" + sbu.toString() + " = 100");}sbu.delete(1, sbu.length());}}public static void main(String[] args) {var n = new Number100();for (int i = 0; i < 5; i++) {new Thread(n::show).start();}}
}


案例六

模拟经典问题,生产者-消费者问题:
方式一:

package day_12_28.zuoye;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** @author soberw* @Classname ProductorAndConsumerForLock* @Description   用线程通信机制解决生产者消费者问题* @Date 2021-12-28 19:18*/
public class ProductorAndConsumerForLock {public static void main(String[] args) {Clerk1 clerk1 = new Clerk1();Productor1 pro = new Productor1(clerk1);Consumer1 con = new Consumer1(clerk1);new Thread(pro, "生产者 A").start();new Thread(con, "消费者 B").start();//         new Thread(pro, "生产者 C").start();
//       new Thread(con, "消费者 D").start();}}class Clerk1 {private int product = 0;private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();// 进货public void get() {lock.lock();try {if (product >= 1) { // 为了避免虚假唤醒,应该总是使用在循环中。System.out.println("产品已满!");try {condition.await();} catch (InterruptedException e) {}}System.out.println(Thread.currentThread().getName() + " : "+ ++product);condition.signalAll();} finally {lock.unlock();}}// 卖货public void sale() {lock.lock();try {if (product <= 0) {System.out.println("缺货!");try {condition.await();} catch (InterruptedException e) {}}System.out.println(Thread.currentThread().getName() + " : "+ --product);condition.signalAll();} finally {lock.unlock();}}
}// 生产者
class Productor1 implements Runnable {private Clerk1 clerk1;public Productor1(Clerk1 clerk1) {this.clerk1 = clerk1;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}clerk1.get();}}
}// 消费者
class Consumer1 implements Runnable {private Clerk1 clerk1;public Consumer1(Clerk1 clerk1) {this.clerk1 = clerk1;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {clerk1.sale();}}}

方式二

package day_12_28.zuoye;/*** @author soberw* @Classname ProducerAndConsumer* @Description 用等待唤醒机制解决生产者消费者问题* @Date 2021-12-28 16:25*/
public class ProductorAndConsumer {public static void main(String[] args) {Clerk clerk = new Clerk();Productor pro = new Productor(clerk);Consumer cus = new Consumer(clerk);new Thread(pro, "生产者 A").start();new Thread(cus, "消费者 B").start();new Thread(pro, "生产者 C").start();new Thread(cus, "消费者 D").start();}}//店员
class Clerk {private int product = 0;//进货public synchronized void get() {//循环次数:0//为了避免虚假唤醒问题,应该总是使用在循环中while (product >= 1) {System.out.println("产品已满!");try {this.wait();} catch (InterruptedException e) {}}System.out.println(Thread.currentThread().getName() + " : " + ++product);this.notifyAll();}//卖货public synchronized void sale() {//product = 0; 循环次数:0while (product <= 0) {System.out.println("缺货!");try {this.wait();} catch (InterruptedException e) {}}System.out.println(Thread.currentThread().getName() + " : " + --product);this.notifyAll();}
}//生产者
class Productor implements Runnable {private Clerk clerk;public Productor(Clerk clerk) {this.clerk = clerk;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {try {Thread.sleep(200);} catch (InterruptedException e) {}clerk.get();}}
}//消费者
class Consumer implements Runnable {private Clerk clerk;public Consumer(Clerk clerk) {this.clerk = clerk;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {clerk.sale();}}
}

案例七

开十个线程打印输出1~10000中偶数的值,计算总耗时
我采用的是闭锁机制:

package day_12_28.zuoye;import java.util.concurrent.CountDownLatch;/*** @author soberw* @Classname CountTime* @Description 开十个线程打印输出1~10000中偶数的值,计算总耗时    用闭锁(门栓)* @Date 2021-12-28 15:22*/
public class CountTime {static CountDownLatch cdl = new CountDownLatch(10);void show() {for (int i = 0; i < 10000; i++) {if (i % 2 == 0) {System.out.println(Thread.currentThread().getName() + ":" + i);}}cdl.countDown();}public static void main(String[] args) {CountTime ct = new CountTime();long start = System.currentTimeMillis();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}for (int i = 0; i < 10; i++) {new Thread(ct::show).start();}try {cdl.await();} catch (InterruptedException e) {e.printStackTrace();}long end = System.currentTimeMillis();System.out.println((end - start - 100) + "--------------");}
}

Java多线程经典案例分享相关推荐

  1. 线程控制总结及多线程经典案例

    线程终止 Linux下有两种方式可以使线程终止: 通过return 从线程函数返回 通过调用函数pthread_exit()使线程退出 #include<pthread.h> void p ...

  2. 利用SEO技术赚钱经典案例分享

    利用SEO技术赚钱相信很多SEOer都想过,平时上上班闲暇时间赚点外快,多爽.首先通过利用SEO技术来做一些项目,是可以赚钱的,而且渠道也是非常多的,但是想要马上实现SEO赚钱也是不易的,因为骗子太多 ...

  3. Java继承多态经典案例分享

    今天动力节点java培训机构小编为大家分享Java继承多态经典案例,希望通过此文能够帮助到大家,下面就随小编一起看看Java继承多态经典案例. public class A { public Stri ...

  4. Java多线程游戏实例分享2-雷火(手把手教你做个超炫酷的星际争霸)

    观前提示: 本文涉及的小成果特别多,即使你不需要写一个和我完全相同的游戏,也可以按照需要查看某些特定功能的实现过程,说不定能够给您的程序开发带来一点小小的启发!PS:结合源代码阅读此博客更加高效. 本 ...

  5. java进程生产者消费者_生产者与消费者(多线程经典案例)

    packageorg.lx.multithreading ;classInfo//定义信息类{privateString name="罗星";//定义name属性privateSt ...

  6. Java多线程(学习分享)

    本文是基于狂神说的多线程讲解,然后加上自己的理解所总结的文章,如有雷同,纯属意外. 同时希望读者在帮助你们的同时,可以对我的不足提出来,大家一同进步~~ 多线程 多线程的概念 线程就是独立的执行路径: ...

  7. Java多线程分析案例

    1. 多线程的创建方式 (1).继承 Thread类:但Thread本质上也是实现了Runnable 接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过 Thread 类的 sta ...

  8. 慢sql治理经典案例分享

    简介:菜鸟供应链金融慢sql治理已经有一段时间,自己负责的应用持续很长时间没有慢sql告警,现阶段在推进组内其他成员治理应用慢sql.这里把治理过程中的一些实践拿出来分享下. 作者 | 如期 来源 | ...

  9. java软件测试经典案例,java语言编程案例 - Mrsjjl的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...

    1.编程实现:二分搜索算法 解答: public class SearchTest { /** 被搜索数据的大小 */ private static final int size = 5000000; ...

最新文章

  1. 好货不能错过!一款在GitHub上22k+star的人力资源管理系统
  2. 《Spring Cloud Netflix官方文档》2. 服务发现:Eureka服务器
  3. C/C++宏定义中#与##区别 .
  4. 《网络编程》守护进程
  5. Java架构师面试问些什么?微服务之springcloud面试题(共22题,含详细解答)
  6. Qt connect parent widget 连接父控件的信号槽
  7. HTML(Hepertext Markup Language 超文本标记语言)
  8. truffle Migration是什么
  9. fileupload 上传文件函数 --把图片名用日期时间命名
  10. 解决进入XP系统无法响应故障
  11. MAC docker 使用阿里加速器
  12. 来曲唑十二烷基硫酸钠/苯丁酸氮芥/层状双金属氢氧化物纳米杂化物
  13. Thinking in Java---如何正确的终止子线程
  14. echarts X轴文字竖向排列 ,一行两字竖向排列或旋转角度排列
  15. linux ssh 远程浏览器,使用浏览器通过ssh连接linux方法
  16. 全平台福利集合大放送!24h后立刻删!冲!
  17. git restore指令和git restore --staged 的使用
  18. 使用fiddler 分析视频网站
  19. 原学而思培优、智联招聘CTO李京峰加盟T3出行
  20. 《资讯:元宇宙》(Yanlz+VR云游戏+Unity+SteamVR+云技术+5G+AI+区块链+NFT+绿洲+头号玩家+平行宇宙+虚拟世界+Pico+Oculus+Soul+立钻哥哥++==)

热门文章

  1. 浅析ODS与EDW关系(转载)
  2. ABP学习笔记:使用EPPlus以表格导出数据
  3. css 圆凹角_css 这种凹陷下去的效果怎么做
  4. 4-python数据容器
  5. 图片如何清除杂物?这几款软件或许可以帮助你
  6. ORM是什么?及ORM框架是什么?
  7. kali工具之convert
  8. 3.3.3JavaScript网页编程——WebAPI(JS之BOM含正则)
  9. 挂载云端硬盘_如何在Linux上挂载Google云端硬盘
  10. bzoj5308[Zjoi2018]胖(线段树,二分,st表)