[Java] 线程和可运行接口

第一步,假设有一个票务销售程序。

创建我的线程

从主函数启动

以下是一个样本。

class Mythread extends Thread {

    private int ticket = 5;
    @Override
    public void run() {
        for(int i =0 ; i<10 ; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
            if(ticket > 0 ) {
                ticket--;
                L.d("残チケット枚数は"+ticket+"枚");
            }
        }
    }
}

public class ThreadSample {

    public static void main(String[] args) {
        Mythread mythread = new Mythread();
        L.d("チケット販売開始");
        mythread.start();
    }
}

结果:
ThreadSample#main:34线程名称:主线程id:1 gentest ::开始售票
Mythread#run:24线程名称:Thread-0线程id:11 gentest ::剩余票数为4张
Mythread#run:24线程名称:Thread-0线程id:11 gentest ::剩余票数为3张
Mythread#run:24线程名称:Thread-0线程id:11 gentest ::剩余票数为2张
Mythread#run:24线程名称:Thread-0线程id:11 gentest ::剩余票数为1张
Mythread#run:24线程名称:Thread-0线程id:11 gentest ::剩余票数为0张

第二步,添加在票务销售完成后的报告(回调)。

创建2.1接口

2.2在主要的类(Main Class)中实现接口。

2.3 添加Mythread的构造函数

2.4 给Mythread的run添加回调

以下是一个样本 shì

interface MyTaskResult {
    void ticketSoldout();
    void ticketRemain();
}

class Mythread extends Thread {
    private MyTaskResult myTaskResult;
    public Mythread (MyTaskResult myTaskResult) {
        this.myTaskResult = myTaskResult;
    }

    private int ticket = 5;
    @Override
    public void run() {
        for(int i =0 ; i<10 ; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
            if(ticket > 0 ) {
                ticket--;
                L.d("残チケット枚数は"+ticket+"枚");
            }
        }
        if(ticket>0) {
            myTaskResult.ticketRemain();
        }else {
            myTaskResult.ticketSoldout();
        }
    }
}

public class ThreadSample {

    public static void main(String[] args) {
        Mythread mythread = new Mythread(myTaskResult);
        L.d("チケット販売開始");
        mythread.start();
    }
    static MyTaskResult myTaskResult = new MyTaskResult() {

        @Override
        public void ticketSoldout() {
            L.d("お疲れ様です。");
        }

        @Override
        public void ticketRemain() {
            L.d("終わっていないの?");
        }
    };
}

The result is… (请刷新)

ThreadSample#main:43 线程名称:主线程 线程ID:1 gentest ::开始售票
Mythread#run:28 线程名称:线程-0 线程ID:11 gentest ::剩余票数为4张
Mythread#run:28 线程名称:线程-0 线程ID:11 gentest ::剩余票数为3张
Mythread#run:28 线程名称:线程-0 线程ID:11 gentest ::剩余票数为2张
Mythread#run:28 线程名称:线程-0 线程ID:11 gentest ::剩余票数为1张
Mythread#run:28 线程名称:线程-0 线程ID:11 gentest ::剩余票数为0张
ThreadSample$1#ticketSoldout:50 线程名称:线程-0 线程ID:11 gentest ::辛苦了。

第三步,使用多台自动售票机销售门票。

3.1 添加可执行的(TicketBox)

增加Thread数量,增加Thread名称(代理1,2,3)

下面是一个示例。

interface MyTaskResult {
    void ticketSoldout(String threadName);
    void ticketRemain(String threadName);
}

class TicketBox implements Runnable {
    private int ticket = 5;
    @Override
    public void run() {
        for(int i =0 ; i<10 ; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
            if(ticket > 0 ) {
                ticket--;
                L.d("残チケット枚数は"+ticket+"枚");
            }
        }
        L.d("完了 チケット:"+ticket);
    }
}

class Mythread extends Thread {
    private MyTaskResult myTaskResult;
    public Mythread (Runnable r, MyTaskResult myTaskResult,String threadName) {
        super(r);
        this.myTaskResult = myTaskResult;
        setName(threadName);
    }

    private int ticket = 5;
    @Override
    public void run() {
        super.run();
    }
}

public class ThreadSample {

    public static void main(String[] args) {
        TicketBox ticketBox = new TicketBox();
        Mythread mythread1 = new Mythread(ticketBox,myTaskResult,"代理1");
        Mythread mythread2 = new Mythread(ticketBox,myTaskResult,"代理2");
        Mythread mythread3 = new Mythread(ticketBox,myTaskResult,"代理3");
        L.d("チケット販売開始");
        mythread1.start();
        mythread2.start();
        mythread3.start();
    }
    static MyTaskResult myTaskResult = new MyTaskResult() {

        @Override
        public void ticketSoldout(String threadName) {
            L.d("お疲れ様です。"+threadName);
        }

        @Override
        public void ticketRemain(String threadName) {
            L.d("終わっていないの?"+threadName);
        }
    };
}

结果 –

ThreadSample#main:52线程名称:main线程ID:1 gentest ::门票销售开始
TicketBox#run:23线程名称:代理2线程ID:12 gentest ::剩余门票数为3张
TicketBox#run:23线程名称:代理1线程ID:11 gentest ::剩余门票数为3张
TicketBox#run:23线程名称:代理3线程ID:13 gentest ::剩余门票数为3张
TicketBox#run:23线程名称:代理1线程ID:11 gentest ::剩余门票数为2张
TicketBox#run:23线程名称:代理2线程ID:12 gentest ::剩余门票数为1张
TicketBox#run:23线程名称:代理3线程ID:13 gentest ::剩余门票数为0张
TicketBox#run:26线程名称:代理2线程ID:12 gentest ::完成 剩余门票:0
TicketBox#run:26线程名称:代理3线程ID:13 gentest ::完成 剩余门票:0
TicketBox#run:26线程名称:代理1线程ID:11 gentest ::完成 剩余门票:0

问题点:
1、5张票卖出了6次。(需要同步处理)
2、每个代理商都没有统计出售了多少张票。

第四步 同步处理

class TicketBox implements Runnable {
    private int ticket = 5;
    @Override
    public void run() {
        for(int i =0 ; i<10 ; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
            saleTicket();
        }
        L.d("完了 残チケット:"+ticket);
    }
    private synchronized void saleTicket() {
        if(ticket > 0 ) {
            ticket--;
            L.d("残チケット枚数は"+ticket+"枚");
        }
    }
}

结果

线程示例#main:55 线程名称:主线程 线程ID:1 gentest ::开始售票
票箱#售票:28 线程名称:代理2 线程ID:12 gentest ::剩余票数为4张
票箱#售票:28 线程名称:代理3 线程ID:13 gentest ::剩余票数为3张
票箱#售票:28 线程名称:代理1 线程ID:11 gentest ::剩余票数为2张
票箱#售票:28 线程名称:代理2 线程ID:12 gentest ::剩余票数为1张
票箱#售票:28 线程名称:代理1 线程ID:11 gentest ::剩余票数为0张
票箱#运行:23 线程名称:代理2 线程ID:12 gentest ::完成,剩余票数:0
票箱#运行:23 线程名称:代理3 线程ID:13 gentest ::完成,剩余票数:0
票箱#运行:23 线程名称:代理1 线程ID:11 gentest ::完成,剩余票数:0

步骤五:销售结果总结。

请参考GitHub。

结果 (jié guǒ)

ThreadSample#main:85 线程名:main 线程ID:1 代理销售测试::开始售票
TicketBox#saleTicket:52 线程名:代理2 线程ID:12 代理销售测试::剩余票数为4张
TicketBox#saleTicket:52 线程名:代理1 线程ID:11 代理销售测试::剩余票数为3张
TicketBox#saleTicket:52 线程名:代理3 线程ID:13 代理销售测试::剩余票数为2张
TicketBox#saleTicket:52 线程名:代理1 线程ID:11 代理销售测试::剩余票数为1张
TicketBox#saleTicket:52 线程名:代理2 线程ID:12 代理销售测试::剩余票数为0张
ThreadSample$1#taskDone:95 线程名:代理1 线程ID:11 代理销售测试::辛苦了,代理1
ThreadSample$1#taskDone:95 线程名:代理2 线程ID:12 代理销售测试::辛苦了,代理2
ThreadSample$1#taskDone:95 线程名:代理3 线程ID:13 代理销售测试::辛苦了,代理3
ThreadSample$1#taskDone:100 线程名:代理3 线程ID:13 代理销售测试::—————-全部完成报告—————————-
ThreadSample$2#sendResult:108 线程名:代理3 线程ID:13 代理销售测试::总票数为:5
ThreadSample$2#sendResult:109 线程名:代理3 线程ID:13 代理销售测试::剩余票数为:0
ThreadSample$2#sendResult:110 线程名:代理3 线程ID:13 代理销售测试::代理1销售结果:2
ThreadSample$2#sendResult:111 线程名:代理3 线程ID:13 代理销售测试::代理2销售结果:2
ThreadSample$2#sendResult:112 线程名:代理3 线程ID:13 代理销售测试::代理3销售结果:1

bannerAds