欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java多线程的常见例子

程序员文章站 2022-03-13 22:07:50
...

一.相关知识:

 

Java多线程程序设计到的知识:

 

(一)对同一个数量进行操作

 

(二)对同一个对象进行操作

 

(三)回调方法使用

 

(四)线程同步,死锁问题

 

(五)线程通信

 

 等等

二.示例一:三个售票窗口同时出售20张票;

程序分析:1.票数要使用同一个静态值

 

 2.为保证不会出现卖出同一个票数,要java多线程同步锁。

 

设计思路:1.创建一个站台类Station,继承Thread,重写run方法,在run方法里面执行售票操作!售票要使用同步锁:即有一个站台卖这张票时,其他站台要等这张票卖完!

 

2.创建主方法调用类

(一)创建一个站台类,继承Thread

 

package com.xykj.threadStation;

public class Station extends Thread {

        // 通过构造方法给线程名字赋值
        public Station(String name) {
             super(name);// 给线程名字赋值
        }       
        // 为了保持票数的一致,票数要静态
        static int tick = 20;
        // 创建一个静态钥匙
        static Object ob = "aa";//值是任意的
        // 重写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();
                }
             
            }
    }
}

 (二)创建主方法调用类

 

package com.xykj.threadStation;
 
public class MainClass {
    /**
     * java多线程同步锁的使用
     * 示例:三个售票窗口同时出售10张票
     * */
    public static void main(String[] args) {
        //实例化站台对象,并为每一个站台取名字
         Station station1=new Station("窗口1");
         Station station2=new Station("窗口2");
         Station station3=new Station("窗口3");
     
        // 让每一个站台对象各自开始工作
         station1.start();
         station2.start();
         station3.start();
     
    }
}

 程序运行结果:

 

窗口2卖出了第20张票
窗口3卖出了第19张票
窗口1卖出了第18张票
窗口2卖出了第17张票
窗口3卖出了第16张票
窗口1卖出了第15张票
窗口1卖出了第14张票
窗口2卖出了第13张票
窗口3卖出了第12张票
窗口2卖出了第11张票
窗口1卖出了第10张票
窗口3卖出了第9张票
窗口2卖出了第8张票
窗口3卖出了第7张票
窗口1卖出了第6张票
窗口2卖出了第5张票
窗口1卖出了第4张票
窗口3卖出了第3张票
窗口3卖出了第2张票
窗口1卖出了第1张票
票卖完了

 可以看到票数是不会有错的!

三.示例二:两个人AB通过一个账户A在柜台取钱和B在ATM机取钱!

程序分析:钱的数量要设置成一个静态的变量。两个人要取的同一个对象值

(一)创建一个Bank类

 

/**两个人AB通过一个账户(2000元)
 * A在柜台取钱和
 * B在ATM机取钱!
 * A一次取出100员,B一次取出200元,直到全部取出。
 * Created by FXY on 2018/6/29.
 */
public class Bank {

    public  static  int money = 2000;


    public void withdrawMoney(int money , String equipment,String name) {
        synchronized (this) {           //加锁同步
            if (equipment.endsWith("counter")&& Bank.money>=money) {
                Bank.money -= money;
                System.out.println(name+"在" + equipment + "取走了" + money + "还剩下" + Bank.money);
            }
            if(equipment.endsWith("atm")&& Bank.money>=money){
                Bank.money -= money;
                System.out.println(name+"在" + equipment + "取走了" + money + "还剩下" + Bank.money);
            }

        }
    }

}

 二)创建一个PersonA类

 

/**
 * Created by FXY on 2018/6/29.
 */
public class PersionA extends Thread{

    Bank bank;

    // 通过构造器传入银行对象,确保两个人进入的是一个银行
    public PersionA(Bank bank) {
        this.bank = bank;
        setName("counter");//给线程命名
    }

    @Override
    public void run(){
        while (Bank.money>=100){
            bank.withdrawMoney(100,"counter",getName());
            try {
                sleep(1000);// 取完休息1秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

 (三)创建一个PersonB类

 

/**
 * Created by FXY on 2018/6/29.
 */
public class PersionB extends Thread{

    Bank bank;

    // 通过构造器传入银行对象,确保两个人进入的是一个银行
    public PersionB(Bank bank) {
        this.bank = bank;
        setName("atm");
    }
    @Override
    public void run() {
        while(Bank.money>=200){
            bank.withdrawMoney(200,"atm",getName());
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }
}

 (四)创建主方法的调用类

 

public class MainClass {
    /**
     * 两个人AB通过一个账户A在柜台取钱和B在ATM机取钱
     * */
    public static void main(String[] args) {
        // 实力化一个银行对象
        Bank bank = new Bank();
        // 实例化两个人,传入同一个银行的对象
        PersonA pA = new PersonA(bank);
        PersonB pB = new PersonB(bank);
        // 两个人开始取钱
        pA.start();
        pB.start();  
    }
}

 运行结果:

 

counter在counter取走了100还剩下1900
atm在atm取走了200还剩下1700
counter在counter取走了100还剩下1600
atm在atm取走了200还剩下1400
counter在counter取走了100还剩下1300
atm在atm取走了200还剩下1100
atm在atm取走了200还剩下900
counter在counter取走了100还剩下800
atm在atm取走了200还剩下600
counter在counter取走了100还剩下500
counter在counter取走了100还剩下400
atm在atm取走了200还剩下200
atm在atm取走了200还剩下0

 可以看到取完就停止运行了。

 

 

今天就写了这俩例子,只要理解了,其他的就简单了!!!!!!

 

还有好几种例子,引用自此处

https://blog.csdn.net/wenzhi20102321/article/details/52524545