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