知识屋:更实用的电脑技术知识网站
所在位置:首页 > 科技

线程java代码实例[7个例子]

发表时间:2022-03-26来源:网络

例子部分参考验证:
https://blog.csdn.net/qq_34996727/article/details/80416277?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-3.channel_param

1 实现线程执行单元
把标题从 1 创建线程 更新为 1 实现线程执行单元的方式。
java中只有Thread代表线程。Runnable只是将业务相关的代码抽象为一个接口。这涉及到一种设计模式:策略模式。
因此创建线程new线程的方式只有一种。
实现线程执行单元线程体的方式有两种。
例1.继承Thread类方式
代码:

package com.whl.thread; /** * 注: * java.lang包中放着java最核心最基础的类、接口:Object、System、Thread、Runnable * Thread.currentThread()获取当前cpu执行线程 */ public class TestThread { public static void main(String[] args) { /** * step 3:在方法中新建一个刚才写的类 */ MyThread myThread = new MyThread();// 线程处于新建状态 myThread.start();// 就绪状态 for(int i = 0;i /** * step 2:复写java.lang.Thread中的run()方法 */ @Override public void run() {// 运行 // TODO 你的线程代码 for(int i = 0;i public static void main(String[] args) { /** * step 3:创建实现类 */ MyRunnable myRunnable = new MyRunnable(); /** * step 4:创建Thread,传入实现类 */ Thread thread = new Thread(myRunnable); /** * step 5:调用start()方法 */ thread.start(); for(int i = 0;i /** * step 2:实现Runnable接口run() */ @Override public void run() { for(int i = 0;i public static void main(String[] args) { /** * step 3:创建线程,创建实现类中传递实参 */ Thread t1 = new Thread(new MyRunnable2(23)); t1.start(); int i = 6; while(i-- > 0){ System.out.println(Thread.currentThread().getName()); } } } class MyRunnable2 implements Runnable { /** * step 1:在实现类中定义局部变量 */ private int age; /** * step 2:定义有参构造方法 * @param age */ public MyRunnable2(int age) { this.age = age; } @Override public void run() { int i = 6; while(i-- > 0){ /** * step 4:使用参数 */ System.out.println(Thread.currentThread().getName() + " 我的年龄是->" + age); } } }

运行结果

使用实现Runnable接口方式更好,原因:
java是单继承多实现;共享资源;数据和程序独立;
例4.两个线程共享资源实现代码:

package com.whl.thread; public class TestThread3 { public static void main(String[] args) { MyRunnable2 myRunnable2 = new MyRunnable2(); myRunnable2.setAge(23); // 两个线程共享变量age Thread t1 = new Thread(myRunnable2); Thread t2 = new Thread(myRunnable2); t1.start(); t2.start(); int i = 10; while(i-- > 0) { System.out.println(Thread.currentThread().getName()); } } } class MyRunnable2 implements Runnable { /** * step 1:在实现类中定义局部变量 * 两个线程共享 */ private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public void run() { int i = 10; while(i-- > 0){ this.age++; System.out.println(Thread.currentThread().getName() + " 我的年龄是->" + age); } } }

运行结果:

3 线程应用例子
例5. 3个站台同时出售火车票,火车票共有20张
代码实现:

package com.whl.example.station; /** * 注明: * static: 在类中的类前加上static,直接通过类名.类名调用; * 在类中的方法前加上static,直接通过类名.方法名调用; * 在类中的变量前加上static,直接同多类名.变量名访问; * 静态变量生命周期是类的生命周期; * * step 1: 创建一个站台类继承java.lang.Thread */ public class Station extends Thread { /** * step 2: 创建有参构造方法,给线程名称赋值 * @param name */ public Station(String name) { super(name); } /** * step 3:创建静态变量,类的变量 */ static int tick = 20; /** * step 4: 创建静态钥匙,类的变量 * * 关键思想:通过[静态,没有static关键字可正常运行]变量的占用判断是否对另一个静态变量操作 */ Object lock = "one"; /** * step 5: 重写run()方法,实现买票操作 */ @Override public void run() { while(tick > 0) { /** * step 6: 每个线程使用同一静态变量,一个线程占用该静态变量时,其他线程不允许进入 * 该线程出来这个代码块后,不使用该静态变量 * * 关键思想:synchronized与静态变量lock配合,操作系统保证cpu只运行三个线程中唯一一个线程中此段代码, * 其他线程不能被执行。唯一一个线程的此段代码运行结束后,cpu可同步执行3个线程线程。 */ synchronized (lock) { if(tick > 0) { System.out.println(getName()+"卖出了第"+tick+"张票"); tick--; }else { System.out.println("票卖完了"); } } try { sleep(500); } catch(Exception e) { e.printStackTrace(); } } } } package com.whl.example.station; public class Main { public static void main(String[] args) { /** * step 7: 创建继承类售票窗口 * 3个窗口 */ Thread t1 = new Station("售票窗口1号"); Thread t2 = new Station("售票窗口2号"); Thread t3 = new Station("售票窗口3号"); /** * step 8: 三个窗口都处于就绪状态 */ t1.start(); t2.start(); t3.start(); } }

运行结果:
问题:同步关键字为什么不写在循环外?
同步关键字写在循环外面代码:

@Override public void run() { synchronized (lock){while(tick > 0) { /** * step 6: 每个线程使用同一静态变量,一个线程占用该静态变量时,其他线程不允许进入 * 该线程出来这个代码块后,不使用该静态变量 * * 关键思想:synchronized与静态变量lock配合,操作系统保证cpu只运行三个线程中唯一一个线程中此段代码, * 其他线程不能被执行。唯一一个线程的此段代码运行结束后,cpu可同步执行3个线程线程。 */ if(tick > 0) { System.out.println(getName()+"卖出了第"+tick+"张票"); tick--; }else { System.out.println("票卖完了"); } try { sleep(500); } catch(Exception e) { e.printStackTrace(); } } }}

运行结果:

结论:同步关键字修饰的代码块,被单独执行。
例6.两个人,一个人每次取钱100元,一个人每次取钱200元,账户里有1000元.
代码实现:

package com.whl.example.person; import java.util.Objects; /** * step 1:创建银行类 */ public class Bank { /** * 创建一个账户,放1000元 * [有没有 static 不影响结果] */ double money = 1000; /** * 提供柜台取钱方法 * @param money */ private void counter(double money) { this.money -= money; System.out.println("柜台取钱"+money+"元,还剩"+this.money+"元!"); } /** * 提供atm取钱方法 * @param money */ private void atm(double money) { this.money -= money; System.out.println("atm取钱"+money+"元,还剩"+this.money+"元!"); } /** * 核心:只要有一个线程被cpu正在执行这个取钱方法,其他都不准执行。 * * 提供取钱方法,设置每次取钱金额,取钱方式 * @param money * @param mode * @throws Exception */ public synchronized void outMoney(double money,String mode) throws Exception { if(money > this.money) { throw new Exception("取款金额"+money+",余额只剩"+this.money+",取款失败!"); } if(Objects.equals(mode,"atm")) { atm(money); }else { counter(money); } } } package com.whl.example.person; /** * step 2:创建一个人继承java.lang.Thread */ public class PersonA extends Thread { Bank bank; String mode; public PersonA(Bank bank,String mode) { this.bank = bank; this.mode = mode; } /** * 每次取钱100,柜台取钱 */ public void run(){ while(bank.money >= 100) { try{ bank.outMoney(100,mode); }catch (Exception e) { e.printStackTrace(); } try{ sleep(100); }catch (Exception e) { e.printStackTrace(); } } } } package com.whl.example.person; /** * step 3:创建一个人继承java.lang.Thread */ public class PersonB extends Thread { /** * 创建账户 */ Bank bank; /** * 创建取钱方式 */ String mode; /** * 提供设置具体取钱方式及账户的方法 * @param bank * @param mode */ public PersonB(Bank bank,String mode) { this.bank = bank; this.mode = mode; } /** * 每次取钱200元,atm取钱 */ public void run(){ while(bank.money >= 200) { try{ bank.outMoney(200,mode); }catch (Exception e) { e.printStackTrace(); } try{ sleep(100); }catch (Exception e) { e.printStackTrace(); } } } } package com.whl.example.person; /** * step 4:创建一个入口类 */ public class Main { public static void main(String[] args) { /** * 实例化一个银行账户 */ Bank bank = new Bank(); /** * 实例化两个继承类,共享这个银行账户 */ PersonA personA = new PersonA(bank,"counter"); PersonB personB = new PersonB(bank,"atm"); /** * 线程处于就绪状态 */ personA.start(); personB.start(); } }

运行结果:

例7.龟兔赛跑
总共200米
乌龟0.1秒跑2米,不休息
兔子0.1秒跑5米,每20米休息1秒
一个赢了,另一个停止跑
实现代码:

package com.whl.example.animal; public abstract class Animal extends Thread { /** * 比赛长度 */ public int length = 200; /** * 抽象方法 * 动物跑 */ public abstract void running(); /** * 复写run() */ public void run(){ super.run(); while (length > 0) { running(); } } /** * 抽象类中声明一个接口 */ public static interface Calltoback { public void win(); } /** * 创建接口对象 */ public Calltoback calltoback; } package com.whl.example.animal; public class Rabbit extends Animal { public Rabbit() { setName("兔子"); } @Override public void running() { int dis = 5; length -= dis; System.out.println("兔子跑了"+dis+"米,距离终点还有"+length+"米"); if(length calltoback.win(); } } try { if((2000 - length) % 20 == 0) {// 每20米休息一次 sleep(1000); }else { sleep(100);// 每0.1秒跑5米 } }catch (Exception e) { e.printStackTrace(); } } } package com.whl.example.animal; public class Tortoise extends Animal { public Tortoise() { setName("乌龟"); } @Override public void running() { int dis = 2; length -= dis; System.out.println("乌龟跑了"+dis+"米,距离终点还有"+length+"米"); if(length calltoback.win(); } } try { sleep(100);// 跑2米停0.1秒 -> 每0.1秒跑2米 } catch (Exception e) { e.printStackTrace(); } } } package com.whl.example.animal; public class LetOneStop implements Animal.Calltoback { Animal animal; public LetOneStop(Animal animal) { this.animal = animal; } public void win(){ // 线程停止 animal.stop(); } } package com.whl.example.animal; public class Main { public static void main(String[] args) { // 乌龟 Tortoise tortoise = new Tortoise(); // 兔子 Rabbit rabbit = new Rabbit(); // 兔子赢了,将乌龟停止 LetOneStop letOneStop1 = new LetOneStop(tortoise); rabbit.calltoback = letOneStop1; // 乌龟赢了,将兔子停止 LetOneStop letOneStop2 = new LetOneStop(rabbit); tortoise.calltoback = letOneStop2; // 跑 tortoise.start(); rabbit.start(); } }

运行结果:

收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜