Java多线程_复习(更新中!!)
java多线程的常见例子
一.相关知识:
Java多线程程序设计到的知识:
(一)对同一个数量进行操作
(二)对同一个对象进行操作
(三)回调方法使用
(四)线程同步,死锁问题
(五)线程通信
等等
二.示例一:三个售票窗口同时出售20张票;
程序分析:1.票数要使用同一个静态值
2.为保证不会出现卖出同一个票数,要java多线程同步锁。
设计思路:1.创建一个站台类Station,继承Thread,重写run方法,在run方法里面执行售票操作!售票要使用同步锁:即有一个站台卖这张票时,其他站台要等这张票卖完!
2.创建主方法调用类
(一)创建一个站台类,继承Thread
package com.com.shundong.thread; /** * @ClassName Station * @Description 三个售票窗口同时出售20张票 * @Author shundong * @Date 2018/12/8 12:31 AM * @Version 1.0 **/ public class Station extends Thread { // 通过构造方法给线程名字赋值 public Station(String name) { super(name);// 给线程名字赋值 } // 为了保持票数的一致,票数要静态 static int tick = 20; // 创建一个静态钥匙 static Object ob = "test";//值是任意的 // 重写run方法,实现买票操作 @Override public void run() { while (tick > 0) { synchronized (ob) {// 这个很重要,必须使用一个锁, // 进去的人会把钥匙拿在手上,出来后才把钥匙拿让出来 if (tick > 0) { System.out.println(getName() + "卖出了第" + tick-- + "张票"); //tick--; } else { System.out.println("票卖完了"); } } try { sleep(1000);//休息一秒 } catch (InterruptedException e) { e.printStackTrace(); } } } // for test public static void main(String[] args) { Station station1 = new Station("站台一"); Station station2 = new Station("站台二"); Station station3 = new Station("站台仨"); station1.start(); station2.start(); station3.start(); } }
程序运行结果:
可以看到票数是不会有错的!
三.示例二:两个人AB通过一个账户A在柜台取钱和B在ATM机取钱!
程序分析:钱的数量要设置成一个静态的变量。两个人要取的同一个对象值。 取钱的方法一定要同步
(一)创建一个Bank类
package com.shundong.day1; /** * @ClassName Bank * @Description 银行 内置柜台 和 ATM 两张方式取钱 * @Author shundong * @Date 2018/12/8 7:31 PM * @Version 1.0 **/ public class Bank { // 假设一个账户有1000块钱 static int money = 1000; // 柜台Counter取钱的方法 public synchronized void Counter(int money) {// 参数是每次取走的钱 Bank.money -= money;//取钱后总数减少 System.out.println("A取走了" + money + "还剩下" + (Bank.money)); } // ATM取钱的方法 public synchronized void ATM(int money) {// 参数是每次取走的钱 Bank.money -= money;//取钱后总数减少 System.out.println("B取走了" + money + "还剩下" + (Bank.money)); } }
(二)创建一个PersonA类
package com.shundong.day1; /** * @ClassName PersonA * @Description 用户A 在柜台取钱 每次 100 * @Author shundong * @Date 2018/12/8 7:31 PM * @Version 1.0 **/ public class PersonA extends Thread{ //创建一个银行对象 Bank bank; // 通过构造器传入银行对象,确保两个人进入的是一个银行 public PersonA(Bank bank) { this.bank = bank; } //重写run方法,在里面实现使用柜台取钱 @Override public void run() { while (Bank.money >= 100) { bank.Counter(100);// 每次取100块 try { sleep(100);// 取完休息0.1秒 } catch (InterruptedException e) { e.printStackTrace(); } } } }
(三)创建一个PersonB类
package com.shundong.day1; /** * @ClassName PersonB * @Description 用户B 在ATM 取款 每次200 * @Author shundong * @Date 2018/12/8 7:33 PM * @Version 1.0 **/ public class PersonB extends Thread { // 创建银行对象 Bank bank; // 通过构造器传入银行对象,确保两个人进入的是一个银行 public PersonB(Bank bank) { this.bank = bank; } // 重写run方法,在里面实现使用柜台取钱 @Override public void run() { while (Bank.money >= 200) { bank.ATM(200);// 每次取200块 try { sleep(100);// 取完休息0.1秒 } catch (InterruptedException e) { e.printStackTrace(); } } } }
(四)创建一个MainClass类 测试
package com.shundong.day1; /** * @ClassName MainClass * @Description 两个人AB通过一个账户A在柜台取钱和B在ATM机取钱 * @Author shundong * @Date 2018/12/8 7:35 PM * @Version 1.0 **/ public class MainClass { //for test public static void main(String[] args) { Bank bank = new Bank(); PersonA personA = new PersonA(bank); PersonB personB = new PersonB(bank); personA.start(); personB.start(); } }
运行MainClass类 结果:
四.示例三:龟兔赛跑问题
龟兔赛跑:20米 //只要为了看到效果,所有距离缩短了
要求:
1.兔子每秒0.5米的速度,每跑2米休息10秒,
2.乌龟每秒跑0.1米,不休息
3.其中一个跑到终点后另一个不跑了!
程序设计思路:
1.创建一个Animal动物类,继承Thread,编写一个running抽象方法,重写run方法,把running方法在run方法里面调用。
2.创建Rabbit兔子类和Tortoise乌龟类,继承动物类
3.两个子类重写running方法
4.本题的第3个要求涉及到线程回调。需要在动物类创建一个回调接口,创建一个回调对象
(一)创建Animal动物类
package com.shundong.dya2; /** * @ClassName Animal * @Description 抽象类 动物 * @Author shundong * @Date 2018/12/8 7:53 PM * @Version 1.0 **/ public abstract class Animal extends Thread { //赛道长度 public double length = 20.00; //抽象的 runing 子类只需要重写 该方法即可 public abstract void runing(); //父类重写的 run 只需要调用 runing即可 @Override public void run() { super.run(); while (length > 0) { runing(); } } //在需要回调数据的地方(两个子类需要),声明一个接口 public static interface Calltoback { public void win(); } //2.创建接口对象 public Calltoback calltoback; }
(二)创建Rabbit兔子类
package com.shundong.dya2; /** * @ClassName Rabbit * @Description 兔子的类 兔子每秒0.5米的速度,每跑2米休息10秒, * @Author shundong * @Date 2018/12/8 8:01 PM * @Version 1.0 **/ public class Rabbit extends Animal { //构造器为 此线程取名 public Rabbit() { setName("兔子"); } //重写 父类 动物类的 runing的 方法 @Override public void runing() { // 跑的距离 double dis = 0.5; length -= dis;//跑完后距离减少 if (length <= 0) { length = 0; System.out.println("兔子获得了胜利"); //给回调对象赋值,让乌龟不要再跑了 if (calltoback != null) { calltoback.win(); } } System.out.println("兔子跑了" + dis + "米,距离终点还有" + (int) length + "米"); if (length % 2 == 0) {// 两米休息一次 时间为 1s 10s太长了 该处为了 方便测试 try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
(三)创建Tortoise乌龟类
package com.shundong.dya2; /** * @ClassName Tortoise * @Description 乌龟类 * @Author shundong * @Date 2018/12/8 8:05 PM * @Version 1.0 **/ public class Tortoise extends Animal { // Thread的方法,给线程赋值名字 public Tortoise() { setName("乌龟"); } // 重写running方法,编写乌龟的奔跑操作 @Override public void runing() { // 跑的距离 double dis = 0.1; length -= dis; if (length <= 0) { length = 0; System.out.println("乌龟获得了胜利"); // 让兔子不要在跑了 回调函数 if (calltoback != null) { calltoback.win(); } } System.out.println("乌龟跑了" + dis + "米,距离终点还有" + (int) length + "米"); try { sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }
(四)创建一个让动物线程停止的类,这里要实现回调接口
package com.shundong.dya2; /** * @ClassName LetOneStop * @Description 处理回调函数 * @Author shundong * @Date 2018/12/8 8:09 PM * @Version 1.0 **/ public class LetOneStop implements Animal.Calltoback { //动物对象 Animal animal; //传过来的 参数 不是乌龟就是兔子 public LetOneStop(Animal animal) { this.animal = animal; } //让线程停止的回调函数 @Override public void win() { //停止线程 animal.stop(); } }
(五)创建一个主方法调用类,
package com.shundong.dya2; /** * @ClassName MainClass * @Description 龟兔赛跑:20米 测试 * @Author shundong * @Date 2018/12/8 8:12 PM * @Version 1.0 **/ public class MainClass { //for test public static void main(String[] args) { //实例化乌龟和兔子 Tortoise tortoise = new Tortoise(); Rabbit rabbit = new Rabbit(); //回调方法的使用,谁先调用calltoback方法,另一个就不跑了 LetOneStop letOneStop1 = new LetOneStop(tortoise); rabbit.calltoback = letOneStop1;//让兔子的回调方法里面存在乌龟对象的值,可以把乌龟stop LetOneStop letOneStop2 = new LetOneStop(rabbit); tortoise.calltoback = letOneStop2;//让乌龟的回调方法里面存在兔子对象的值,可以把兔子stop //开始跑 tortoise.start(); rabbit.start(); } }
运行MainClass类 结果:
待续。。。。
Java多线程_复习(更新中!!)的更多相关文章
- Java多线程4:Thread中的静态方法
一.Thread类中的静态方法 Thread类中的静态方法是通过Thread.方法名来调用的,那么问题来了,这个Thread指的是哪个Thread,是所在位置对应的那个Thread嘛?通过下面的例子可 ...
- Java多线程笔记[未更新完]
最近课上可摸鱼时间较多,因此并发开坑学习 本篇学习自Java多线程编程实战指南 目前进展:刚开坑,处于理解概念阶段 本篇学习自Java多线程编程实战指南 Q.进程和线程的区别 进程Process是程序 ...
- Java多线程_生产者消费者模式2
在我的上一条博客中,已经介绍到了多线程的经典案列——生产者消费者模式,但是在上篇中用的是传统的麻烦的非阻塞队列实现的.在这篇博客中我将介绍另一种方式就是:用阻塞队列完成生产者消费者模式,可以使用多种阻 ...
- 1.java多线程_实现线程的两种方式
1.java多线程基本知识 1.1.进程介绍 不管是我们开发的应用程序,还是我们运行的其他的应用程序,都需要先把程序安装在本地的硬盘上.然后找到这个程序的启动文件, 启动程序的时候,其实是电脑把当前的 ...
- java多线程2:Thread中的方法
静态方法: Thread类中的静态方法表示操作的线程是"正在执行静态方法所在的代码块的线程". 为什么Thread类中要有静态方法,这样就能对CPU当前正在运行的线程进行操作.下面 ...
- Java基础——集合(持续更新中)
集合框架 Java.util.Collection Collection接口中的共性功能 1,添加 booblean add(Object obj); 往该集合中添加元素,一次添加一个 boolea ...
- Java多线程_缓存对齐
1.什么是缓存对齐 当前的电脑中,数据存储在磁盘上,可以断电保存,但是读取效率较低.不断电的情况下,数据可以在内存中存储,相对硬盘效率差不多是磁盘的一万倍左右.但是运算时,速度最快的是直接缓存在CPU ...
- Java多线程_并发容器ConcurrentHashMap/CopyOnWriteArrayList/CopyOnWriteArraySet
ConcurrentHashMap HashMap是线程不安全的,可以使用Collections.synchronizedMap(map)把一个不安全的map变成安全的,但是这里可以直 ...
- Java多线程2:Thread中的实例方法
Thread类中的方法调用方式: 学习Thread类中的方法是学习多线程的第一步.在学习多线程之前特别提出一点,调用Thread中的方法的时候,在线程类中,有两种方式,一定要理解这两种方式的区别: 1 ...
随机推荐
- [20190415]11g下那些latch是共享的.txt
[20190415]11g下那些latch是共享的.txt http://andreynikolaev.wordpress.com/2010/11/23/shared-latches-by-oracl ...
- sql判断字段是否为空
sql语句条件查询时,有时会判断某个字段是否为空. 字段内容为空有两种情况 1.为null 2.为字符串的空'' 语句如下: select * from table where column is n ...
- wxPython的简单应用
- Java Api Consumer 连接启用Kerberos认证的Kafka
java程序连接到一个需要Kerberos认证的kafka集群上,消费生产者生产的信息,kafka版本是2.10-0.10.0.1: Java程序以maven构建,(怎么构建maven工程,可去问下度 ...
- 从开始到头皮炸裂的python第5天
头皮炸裂的一天从学到一个新的数据类型开始,这个数据类型的新成员叫做字典,基本的格式为data={键:值,键:值},info.keys()表示所有的键,info.values()表示所有的值,info. ...
- [LeetCode] 4. 寻找两个有序数组的中位数
题目链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 题目描述: 给定两个大小为 m 和 n 的有序数组 nums1 和 ...
- web服务器、tomcat、servlet是什么?它们之间的关系又是什么?
今天偶然看到常见web服务器的介绍有Apache HTTP server.Nginx.Microsoft IIS.GWS,心中不禁产生了疑问,这些都是什么呢?一直认为tomcat就是web服务器,以下 ...
- c# 7.0 6.0 新语法
1.参考地址:https://docs.microsoft.com/zh-cn/dotnet/csharp/tutorials/exploration/csharp-7?tutorial-step=5 ...
- 使用exec和sp_executesql动态执行SQL语句(转载)
当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句,个人觉得用得比较多的地方就是分页存储过程和执行搜索查询的SQL语句.一个比较通用的分页存储过程,可能需要传入表名, ...
- root用户无法访问Mysql数据库问题的解决
在使用Centos系统远程访问Mysql数据库的时候,系统提示报如下错误: Access Denied for User 'root'@'localhost' (using password: YES ...