PHP 程序员学习 java 入门线程通信

线程通信

java 提供了 waitnotify 方法来阻塞和唤醒。

使用场景设想

比如:酒店的房间,例如10间房客,入住一个客户之后,当住满10个之后,如果下个客户需要进来,需要等待另外一个客户不住了才能住进去。否则就冲突了。这个时候可以通过线程来解决这个问题

例子

描述

Hotel

package com.kongqi.hotel;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class Hotel {
    //房间数定义,存为一个安全线程的ArrayList
    private static List<String> roomList= new CopyOnWriteArrayList<>();
    private static  int roomNumber=10;

    /**
     * 入住
     */
    public synchronized static void in(){
        if(roomList.size()==roomNumber){
            System.out.println("当前没有空余的房间入住,请稍后等待");
            //没有房间。需要等待客户离开入住。
            try {
                Hotel.class.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }else{
            roomList.add("people");//随便入住一个人
            System.out.println("当前房客入住了一间,当前入住房间数:" + roomList.size());
            //释放阻塞
            Hotel.class.notify();
            //延迟一下
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
    public synchronized static void out(){
        //如果没有入住就没有离开
        if(roomList.size()==0){
            System.out.println("当前没有房客入住");
            //等待客户入住
            try {
                Hotel.class.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else{
            roomList.remove(0);//先进先出,假设
            System.out.println("当前房客离开了一间,当前入住房间数:" + roomList.size());
            //释放阻塞
            Hotel.class.notify();
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

UserInThread

package com.kongqi.hotel;

public class UserInThread extends Thread {
    public UserInThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        while (true){
            Hotel.in();//一直循环入住
        }
    }
}

UserOutThread

package com.kongqi.hotel;

public class UserOutThread extends Thread {
    public UserOutThread(String name) {
        super(name);
    }
    @Override
    public void run() {
       while (true){
           Hotel.out();//一直循环离开
       }
    }
}

HotelDemo

package com.kongqi.hotel;

public class HotelDemo {
    public static void main(String[] args) {
        //运行线程看看
        Thread userIn=new UserInThread("入住");
        Thread userOut=new UserOutThread("离开");
        userIn.start();
        userOut.start();
    }
}

线程join

等待一个线程死亡,之后再执行其他线程。
场景探索
比如我们需要先完成播种,然后才能收割;

SeedDemo

package com.kongqi.seed;

public class SeedDemo {
    public static void main(String[] args) {
        Thread seedThread=new SeedThread();
        Thread seedResultThread = new SeedResultThread();
        seedThread.start();
        seedResultThread.start();
    }
}

SeedThread

package com.kongqi.seed;

public class SeedThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("播种子,已播"+i);
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

SeedResultThread

package com.kongqi.seed;

public class SeedResultThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("已收割,已收"+i);
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

如果这样演示下,如下
描述
我们还没有播种,就开始了收割了。这不符合我们的需求。

public class SeedDemo {
    public static void main(String[] args) {
        Thread seedThread=new SeedThread();
        Thread seedResultThread = new SeedResultThread();
        seedThread.start();
        try {
            seedThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        seedResultThread.start();
    }
}

修改之后演示
描述

线程中断 interrupt

比如我们上面的例子,我们收割到一半就不收割了。

package com.kongqi.seed;

public class SeedResultThread extends Thread {
    @Override
    public void run() {
        try {
            for (int i = 0; i < 20; i++) {
                System.out.println("已收割,已收" + i);
                //收割到一半的时候,我们就不收割了
                if (i == 10) {
                    this.interrupt();//中断
                }
                this.sleep(400);

            }
        } catch (InterruptedException e) {
            System.out.println("收割停止");
            //e.printStackTrace();
        }
    }
}

描述

如果你觉得本站帮助到您,麻烦您帮点个小广告支持下本站,感谢不尽。

评论区 (0)

没有记录
支持 markdown,图片截图粘贴拖拽都可以自动上传。

公告通知

关于网站广告,由于需要营运成本,所以增加了广告联盟。
如果你觉得本站帮助到您,麻烦您帮点个小广告,感谢不尽。

空气

空气

热卖技术,喜欢新东西。

周VIP 魔童降世
查看更多

最新视频课程

Laravel 消息通知使用

Laravel 的 PhpSpreadsheet 包入门

ace.js 打造一款属于你的 Web 编辑器,入门文档。

wap2App 入门讲解,100%速成,全面为你讲解。

Laravel Permission 中文文档

Laravel 设置请求头 header 参数

Laravel 实现 RBAC 权限管理功能 Permission 包操作

解释 OAuth 2.0 认证 和使用场景说明

KongQi Laravel Admin2.0 文档安装

KongQi Laravel admin2.0 layui admin 版本序言

黑白课堂社区使用如何购买元宝和开通 VIP

易语言入门拖入文件导入到超级列表框表格内

易语言入门易语言定时任务模块

Visual Studio Code 入门和使用教程安装下载

易语言入门TAB 标签页制作

黑白课堂社区使用社区规范说明

钻级赞助商