进程:系统资源分配的单位;
线程:处理器任务调用和执行的单位,线程之间共享进程资源;
今天先学习两种API定义的线程创建方式:1.继承Thread类;2.实现Runnable接口。
1.方式一:继承Thread类创建线程;
//1.自定义类继承Thread类//2.重写Thread类中的run()方法//2.1要执行的内容写在run()方法内//3.在测试类中创建自定义类实例//4.开启进程start()//4.1一个自定义的实现类只能开启一个线程,只能调用一次start()方法
//1.自定义类继承Thread类classMyThreadextendsThread{ //2.重写Thread类中的run()方法publicvoidrun() { //需要执行的内容:输出0-100之内的偶数for (inti=0; i<100; i++) { if (i%2==0) //Thread.currentThread().getName():获取当前线程的名字System.out.println(Thread.currentThread().getName()+":"+i); } } } publicclassDemoThread { publicstaticvoidmain(String[] args) { //3.在测试类中创建自定义类实例MyThreadmt=newMyThread(); //4.开启进程start()mt.start(); } }
2.方式二:实现Runnable接口创建线程;
//1.自定义类实现Runnable接口//2.实现Runnable接口中的run()方法//2.1要执行的内容写在run()方法内//3.创建自定义类的实例对象//4.创建Thread类对象,并把第三部创建的自定类的实例对象当做参数传给Thread构造器//5.使用Thread类对象,调用start()方法,开启线程
//1.自定义类实现Runnable接口classMyRunnableimplementsRunnable{ //2.实现Runnable接口中的run()方法publicvoidrun() { //需要执行的内容:输出0-100之内的偶数for (inti=0; i<100; i++) { if (i%2==0){ System.out.println(Thread.currentThread().getName() +":"+i); } } } } publicclassDemoRunnable { publicstaticvoidmain(String[] args) { //3.创建自定义类的实例对象MyRunnablerunnable=newMyRunnable(); //4.创建Thread类对象,并把第三部创建的自定类的实例对象,当做参数传给Thread构造器Threadthread=newThread(runnable); //5.使用Thread类对象,调用start()方法,开启线程thread.start(); } }
注意事项:
1.为什么使用thread.start()开始了线程,却执行了实现Runnable接口中实现的run()方法?
2.Thread类底层,也实现了Runnable接口;
继承Thread类和实现Runnable接口的区别:
在两种创建线程的方法中优先选择:实现Runnable接口;
1.实现Runnable接口,避免了Java中类只能单继承的局限性;
2.实现Runnable接口,能实现资源共享;继承Thread类则需要声明为static才能实现资源共享。
(实现Runnable接口,它的实现类只用创建一次,只要创建多个Thread类,就能实现创建多个线程,天然的资源共享;继承Thread类,每创建一个线程,就需要创建一个继承自Thread类的子类,如果不把资源声明为static,则每创建一个继承自Thread类的子类,就会有一个新的资源...)
使用多线程实现买100张票:
继承Thread类(存在线程不安全的问题,会出现重票的现象,在后续线程同步的时候会讲。)
实
现Runnable接口也是一样的效果,这里不在演示。
publicclassPraSaleTicket { publicstaticvoidmain(String[] args) { Salesale01=newSale(); Salesale02=newSale(); Salesale03=newSale(); //修改线程的名字,后续会详讲(修改线程名字要在开启线程之前)sale01.setName("窗口01"); sale02.setName("窗口02"); sale03.setName("窗口03"); sale01.start(); sale02.start(); sale03.start(); } } classSaleextendsThread{ //将票数声明为static表示,当前票数是当前类共享的privatestaticintticket=100; publicvoidrun() { while (true){ if (ticket>0) { //因为当前类继承了Thread类,所以可以直接调用getName()获取当前线程的名字 System.out.println(getName() +"_票号为:"+ticket); ticket--; } else { break; } } } }