多线程基础

线程是程序执行的最小单位。如果说QQ是一个进程的话,它就像一个容器,管理和分配着资源。QQ能同时做很多事情,比如接收消息,发送消息,在内置浏览器里冲浪。而同时进行这些事情就需要线程这个概念了。也就是说进程相当于资源分配平台,而线程则是资源调度的基本单位。

创建线程的两种方式

举个例子,把一个羽毛球馆想象成一个进程,里面都多个场地在同时进行比赛(线程)。

继承Thread类创建线程

于是我们先定义一个Player类,为其声明进攻方法和判断胜利方法。

public class Player {

    private String name;
    private int score=0;
    private double attackRate;  // 进攻成功率
    private double defenseRate; // 防守成功率
    public Player(String name){
        this.name = name;
    }

    public void offense(Player p){
        this.attackRate = Math.random();
        this.defenseRate = Math.random();
        p.attackRate = Math.random();
        p.defenseRate = Math.random();
        try {
            Thread.sleep(500); // 模拟间歇,攻防后休息一下
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (this.attackRate > p.defenseRate){
            this.score += 1;
            System.out.format("%s 进攻 %s成功, %s的得分变为 %d%n",this.name,p.name,this.name,this.score);
        }
        if(this.isWin())
            System.out.println(this.name +"取得胜利!");
    }

    public boolean isWin() {
        return this.score >= 5;
    }
}

再定义一个线程类OffenseThred继承Thread类,重写run方法,这个方法是线程执行的主体内容。这个类表示一个场地内进行的一场比赛(线程)。

public class OffenseThread extends Thread{

    private Player p1;
    private Player p2;

    public OffenseThread(Player p1, Player p2){
        this.p1 = p1;
        this.p2 = p2;
    }

    @Override // 重写run方法
    public void run(){
        while (true){
            if (p1.isWin() || p2.isWin()){break;}
            else {
                p1.offense(p2);
                p2.offense(p1);
            }
        }
    }

最后写一个测试类,测试一下多线程同时进行的效果。

public class BadmintonGame {
    public static void main(String[] args) {
        Player linDan = new Player("林丹");
        Player liZongS = new Player("李宗盛");

        Player zs = new Player("张三");
        Player ls = new Player("李四");

        // 通过创建线程对象
        OffenseThread offenseThread1 = new OffenseThread(linDan, liZongS); // 职业组比赛线程
        offenseThread1.start(); // 调用start()方法
        OffenseThread offenseThread2 = new OffenseThread(zs, ls); // 业余组比赛线程
        offenseThread2.start();
    }

效果如下,可以看到两场比赛(线程)是同时进行的。
在这里插入图片描述

实现Runnable接口

创建一个OffenseRun类去实现Runnable接口并实现run方法:

public class OffenseRun implements Runnable{ 

    private Player p1;
    private Player p2;

    public OffenseRun(Player p1, Player p2){
        this.p1 = p1;
        this.p2 = p2;
    }

	// 实现run方法
    public void run(){
        while (true){
            if (p1.isWin() || p2.isWin()){break;}
            else {
                p1.offense(p2);
                p2.offense(p1);
            }
        }
    }
}

创建OffenseRun的对象,最后将对象作为参数传入Thread构造方法中,创建线程对象,调用start方法执行线程。

 // 实现runable接口 将对象作为参数传入Thread构造方法中
	OffenseRun offenseRun1 = new OffenseRun(linDan, liZongS);
	new Thread(offenseRun1).start();
	OffenseRun offenseRun2 = new OffenseRun(zs, ls);
	new Thread(offenseRun2).start();

两种方法的比较

通过实现Runnable接口的方法比前者要更加灵活,因为前者继承了Thread类就不能继承其他类了。实现Runnable的方法可以更方便地实现多个线程共享数据的行为。
其实平常开发中,有关线程的具体操作都不要自己动手,基本都由各种优秀的框架封装实现了。自己只需要加上注解,设置一些线程上的参数即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值