前言
接下来我们进入到多线程的学习,向着胜利稳步迈进
步骤
1.多线程的概念
举一个通俗一点的例子,我们在过年回家的时候,离家比较远的同学就要用手机抢票软件进行抢票了,同时多人在同一个手机APP上进行抢票,这就是一个多线程的体现,如果没有多线程,那么一个人抢票,那么其他人只能干瞪眼排队,等着他买完,效率大大降低。
2.多线程实现的方式
- 继承Thread类:继承Thread类后,重写run()方法,填写方法体,使用对象.start()进行调用
package com.jwang.test;
public class Test extends Thread{
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("######一边玩游戏######");
}
}
public static void main(String[] args) {
Test test = new Test();
test.start();
for (int i = 0; i < 200; i++) {
System.out.println("******一边学习******");
}
}
}
- 实现Runnable接口:必须重写run()方法,填写方法体,使用 new Thread(对象).start()进行调用
package com.jwang.test;
public class Test implements Runnable{
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("######一边玩游戏######");
}
}
public static void main(String[] args) {
Test test = new Test();
new Thread(test).start();
for (int i = 0; i < 200; i++) {
System.out.println("******一边学习******");
}
}
}
这样的话,就可以做到一边玩游戏,一边学习了,虽然说有点荒唐,哈哈哈。
听多线程的概念总是有些枯燥,那么我们模拟两个例子玩玩,抢票以及龟兔赛跑
抢票:许多票贩子和急着回家的你一起抢票
package com.jwang.test;
public class Grab implements Runnable {
//上海-->老家的火车票,目前余票500张
private Integer vote = 500;
//抢票
@Override
public void run() {
while (true) {
//你的网速要比黄牛慢一点点
//比不上票贩子,速度慢半拍
if("你".equals(Thread.currentThread().getName())){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (this){
if(this.vote>0){
System.out.println(Thread.currentThread().getName()+"抢到了一张票,目前火车票剩余"+(--vote)+"张");
}else {
break;
}
}
}
}
public static void main(String[] args) {
Grab grab = new Grab();//拿起抢票软件,抢同一路线的票
//以下代码顺序不代表执行顺序
//黄牛甲与黄牛乙同时和你抢票//看结果如何吧
Thread ni = new Thread(grab,"你");
Thread h1 = new Thread(grab,"黄牛甲");
Thread h2 = new Thread(grab,"黄牛乙");
ni.start();
h1.start();
h2.start();
}
}
下面来看以下结果吧,也就是慢了那么一丢丢,?,截取运行结果一部分,所以我们每次春运回家难啊,博主也是如此,,,
龟兔赛跑:兔子和龟的故事
package com.jwang.test;
public class Sport implements Runnable {
private String winner;//胜利者
@Override
public void run() {
//规定跑满100步就算赢了
for(int step=1;step<=100;step++){
//由于兔子睡觉,每隔20步它就休息一下
if("兔子".equals(Thread.currentThread().getName()) && step%20==0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"跑了"+step+"步");
boolean flag = isGameOver(step);
if(flag){
break;
}
}
}
public boolean isGameOver(int step){
if(winner != null){
return true;
}else {
if(step == 100){
winner = Thread.currentThread().getName();
System.out.println("胜利者是:"+Thread.currentThread().getName());
return true;
}
}
return false;
}
public static void main(String[] args) {
Sport sport = new Sport();
Thread gui = new Thread(sport,"乌龟");
Thread tu = new Thread(sport,"兔子");
gui.start();
tu.start();
}
}
我们知道,龟兔赛跑的结果是乌龟赢,所以运行结果其一是:
3.静态代理设计模式
我们先举一个例子,一个公司有一个领导,他身边有个秘书。领导相当于真实的对象,秘书相当于领导的一个代理。
作用:为其他对象提供一种代理以控制对这个对象的访问。
设计领导类:Leader、秘书类:Secretary以及公共的接口会议:Meeting,会议接口有抽象方法开会:holdMeeting()
代码实现如下:
package com.jwang.test;
//会议接口
interface Meeting{
//抽象开会方法
public void holdMeeting();
}
//领导类:真实对象
class Leader implements Meeting{
private String name;//领导姓名
public Leader(String name) {
this.name = name;
}
@Override
public void holdMeeting() {
System.out.println(this.name+"开会。。。");
}
}
//秘书类:代理对象
class Secretary implements Meeting{
private String name;//秘书姓名
private Leader leader;//所属领导
public Secretary(String name, Leader leader) {
this.name = name;
this.leader = leader;
}
@Override
public void holdMeeting() {
System.out.println(this.name+"布置会场,通知与会人员开会!");//秘书干的活
this.leader.holdMeeting();//领导的任务
System.out.println(this.name+"撰写会议纪要!");//秘书干的活
}
}
public class ProxyTest {
public static void main(String[] args) {
//生成代理对象
Secretary secretary = new Secretary("女秘书A", new Leader("王总"));
secretary.holdMeeting();//开会
}
}
以上代码中,秘书A将王总不需要干的但又不得不做的活做了,极大的提高了王总的开会效率。
大家思考一下,Thread类是不是也是静态代理模式的一种实现呢?
4.线程的状态
状态,即线程的生命周期,包含以下部分(箭头表示可以达到的状态):
我们可以形象的把他比喻为一个足球队。
- 开始:组建球队,一个教练+11个足球队员-->建立线程若干
- 就绪:球员入场参加比赛-->调用start()方法进入就绪状态等待CPU调度
- 运行中:球员抢到了球,带球跑-->CPU调度了某个线程
- 阻塞:球员被对手干扰,无法继续带球-->程序使用了sleep()等方法或其他原因导致线程阻塞
- 终止:球员因为犯规等原因被罚出场-->程序正常终止或者调用了stop()等方式导致线程死亡
目前来讲,我的项目中还没有使用多线程的概念,我这里也就浅尝辄止,有兴趣的同学可以多多学习,后续我有时间会继续深入的去理解