java 线程 资源_Java多线程、主线程等待所有子线程执行完毕、共享资源
发布日期:2022-02-03 04:38:25 浏览次数:9 分类:技术文章

本文共 3851 字,大约阅读时间需要 12 分钟。

1.Java创建与启动线程

Java提供两种方式创建和启动线程:1.直接Thread类,2.实现Runable接口。

1.1  继承Thread类

public class myThread extends Thread {

public void run(){

for(int i=0;i<5;i++){

System.out.println(this.getName()+":"+i);

}

}

public static void main(String[] args){

//创建3个线程

myThread myThread1 = new myThread();

myThread myThread2 = new myThread();

myThread myThread3 = new myThread();

//启动线程

myThread1.start();

myThread2.start();

myThread3.start();

}

}

c20022d8279f26c5d2fb05566b5705a0.png

线程1,2,3,随机执行

注意启动线程一定要用thread.start()而不能用thread.run()。否则则是顺序执行,失去多线程的意义。

public class myThread extendsThread {public voidrun(){for(int i=0;i<5;i++){

System.out.println(this.getName()+":"+i);

}

}public static voidmain(String[] args){//创建3个线程

myThread myThread1 = newmyThread();

myThread myThread2= newmyThread();

myThread myThread3= newmyThread();//启动线程

myThread1.run();

myThread2.run();

myThread3.run();

}

}

输出结果:三个线程顺序执行

f7fca80c1f3e16f0577dbf86af878919.png

1.2 实现Runnable接口实现

public class myRunnable implementsRunnable {privateString name;public voidrun() {for(int i=0;i<5;i++){

System.out.println(this.getName()+":"+i);

}

}publicString getName() {returnname;

}publicmyRunnable(String name) {super();this.name =name;

}public static voidmain(String[] args){//创建3个线程

myRunnable myRunnable1 = new myRunnable("thread1");

myRunnable myRunnable2= new myRunnable("thread2");

myRunnable myRunnable3= new myRunnable("thread3");//启动线程,由于runnable中是没有start方法的,这里要将你的runnable实例作为Thread(Target target)参数,启动线程//多个Runnable实例,执行相同代码

newThread(myRunnable1).start();newThread(myRunnable2).start();newThread(myRunnable3).start();

}

}

执行结果:随机执行

4e29c244d0d24def736afa692e15bdad.png

2.两种方式有什么不同,再看下面的代码,利用Runnable 实现资源共享,这里的共享知识部分共享

比如售票系统

1 public class myThread extendsThread {2 private int tickets=5;//总共5张票

3 public voidrun(){4 for(int i=0;i<10;i++){5 if(tickets>0){6 System.out.println(this.getName()+":"+tickets--);7 }8 }9 }10

11 public static voidmain(String[] args){12 //创建3个线程

13 myThread myThread1 = newmyThread();14 myThread myThread2 = newmyThread();15 myThread myThread3 = newmyThread();16 //启动线程

17 myThread1.start();18 myThread2.start();19 myThread3.start();20 }21 }

输出结果:每个线程都卖了5张票,相当于15张票

a271bd444649e33c2c4fa20b5d70aade.png

那么再来看看使用Runnable 实现三个进程共享系统中的5张票

public class myRunnable implementsRunnable {private int tickets=5;public voidrun() {for(int i=0;i<10;i++){if(tickets>0){

System.out.println(Thread.currentThread().getName()+"正在卖票:"+tickets--);

}

}

}public static voidmain(String[] args){//创建3个线程

myRunnable myRunnable1 = newmyRunnable();//启动线程,由于runnable中是没有start方法的,这里要将你的runnable实例作为Thread(Target target)参数,启动线程//通过一个Runnable实例,创建3个线程,该三个线程共享tickets这个资源

new Thread(myRunnable1,"1号窗口").start();new Thread(myRunnable1,"2号窗口").start();new Thread(myRunnable1,"3号窗口").start();

}

}

输出结果:三个线程共享了5张票

3ff5fe509c031deb0f0ba24f7bc757e5.png

利用实例化一个Runnable对象,实现共享

3.大家注意了,多线程开发中,主线程和子线程是并发执行的,也就是,子线程在执行的过程中,主线程也在往下执行。这就导致了有这么一个需求不好实现。那就是,主线程需要所有子线程返回执行结果才能继续执行。同志们这个怎么实现呢?

ok,我们利用一个CountDownLatch来实现

1 public class MyRunnableReturn implementsRunnable {2 privateCountDownLatch threadsSingal;3

4

5 publicMyRunnableReturn(CountDownLatch threadsSingal) {6 super();7 this.threadsSingal =threadsSingal;8 }9

10

11 public voidrun() {12 System.out.println(Thread.currentThread().getName()+"--开始");13 System.out.println(Thread.currentThread().getName()+"--结束");14 threadsSingal.countDown();//线程减1

15 }16

17 public static voidmain(String [] agrs){18 System.out.println("Main --开始");19 CountDownLatch threadsSingal=new CountDownLatch(3);20 MyRunnableReturn myRunnable=newMyRunnableReturn(threadsSingal);21 new Thread(myRunnable,"thread1").start();22 new Thread(myRunnable,"thread2").start();23 new Thread(myRunnable,"thread3").start();24 try{25 threadsSingal.await();//等待所有子线程执行完

26 } catch(InterruptedException e) {27 //TODO Auto-generated catch block

28 e.printStackTrace();29 }30 System.out.println("Main --结束");31 }32 }

输出结果:主线程等待所有子线程执行完毕,然后在执行

6395be2c5c2b3117f40f22c832c0a6da.png

4.问题又来了,现实开发中,有可能,需要不同Runnable根据不同的数据执行相同的代码,这个又如何实现呢?

这就又导致了,通过只实例化一个Runnable对象来进行共享资源的方法不可行了。我们可以通过将共享数据封装成一个对象,传给不同的Runnable线程对象。达到资源共享

转载地址:https://blog.csdn.net/weixin_30596151/article/details/114229187 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:jvm和java内存模型_聊聊我对Java内存模型的理解
下一篇:java有多大_一个 Java 对象到底有多大?

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月02日 04时12分52秒