1 /* 2 * 注线程:执行主(main)方法的线程 3 * 4 * 单线程程序:java程序中只有一个线程执行从main方法开始,从上到下依次执行 5 * 6 * 7 * jvm执行main方法,main方法会进入到栈内存 8 * jvm会找操作系统开辟一条mian方法向cpu的执行路径 9 * cpu就可以通过这个路径来执行main方法 10 * 而这个路径有个名字叫做:主线程 11 * 12 * 13 *缺点: 14 * 中途如果报了异常 15 * 下一个进程就不会运行 16 * 17 * 18 */ 19 public class Demo01MainThread { 20 public static void main(String[] args){ 21 Person p1 = new Person("小明"); 22 p1.run(); 23 24 System.out.println(0/0); 25 26 Person p2 = new Person("小强"); 27 p2.run(); 28 } 29 30 31 32 33 34 35 public class Person { 36 37 private String name; 38 39 public void run(){ 40 //定义循环,执行20次 41 for(int i=0;i<20;i++){ 42 System.out.println(name+i); 43 } 44 } 45 46 public Person() { 47 } 48 49 public Person(String name) { 50 super(); 51 this.name = name; 52 } 53 54 public String getName() { 55 return name; 56 } 57 58 public void setName(String name) { 59 this.name = name; 60 } 61 62 }
创建多线程的第一种方式:
1 /* 2 * 创建多线程程序的第一种方式:创建Thread的子类 3 * java.lang.Thread类:是描述线程的类,我们箱套实现,多线程程序,就必须继承Thread类 4 * 5 * 实现步骤: 6 * 1、创建一个Thread类的子类 7 * 2、在Thread类的子类中重写Thread类中的run方法。设置线程任务(开启线程要做什么?) 8 * 3、创建Thread的子类对象 9 * 4、调用Thread类中的方法start方法,开启新的线程,执行run方法 10 * void start()使线程开始执行:java虚拟机调用该线程的run方法 11 * 结果是俩个线程并发地运行,当主线程和另一个线程(创建的新线程,执行其run方法) 12 * 多次启动一个线程是非法的,特别是线程已经结束之后,不能再重新启动 13 * java属于抢占式调度,哪个线程的优先级高,哪个线程就会优先执行,同一个优先级,随机选则一个执行 14 * 15 */ 16 public class Demo01Thread { 17 public static void main(String[] args){ 18 //创建Thread子类对象 19 MyThread mt = new MyThread(); 20 //4、调用Thread类中的方法start方法,开启新的线程,执行run方法 21 22 mt.start(); 23 24 for(int i=0;i<20;i++){ 25 System.out.println("main"+i); 26 } 27 } 28 } 29 30 31 32 33 34 35 // 1、创建一个Thread类的子类 36 public class MyThread extends Thread{ 37 38 //2、在Thread类的子类中重写Thread类中的run方法。设置线程任务(开启线程要做什么?) 39 @Override 40 public void run() { 41 for(int i=0;i<20;i++){ 42 System.out.println("run"+i); 43 } 44 45 } 46 47 }
Thread类的常用方法和获取线程名称:
自定义线程类: /* * 获取线程的名称: * 1、使用Thread类中的方法getName() * String getName()返回该线程的名称 * 2、可以获取当前正在执行的线程,使用线程中的方法gerName()获取线程名称 * static Thread currentThread()返回对当前正在执行的线程对象的引用。 * */ //定义一个Thread类的子类 public class MyThread extends Thread { @Override public void run() { //获取线程的名称 // String name = getName(); // System.out.println(name); // Thread t=Thread.currentThread(); // System.out.println(t);//获取当前执行的线程 Thread[Thread-0,5,main] // String name = t.getName(); // System.out.println(name);//可以缩短为一行 //链式编程 System.out.println(Thread.currentThread().getName()); } //重写Thread类中的run方法,设置线程任务 } 测试类: /* 线程的名称: * 主线程:main * 新线程:Thread-0、Thread-1、Thread-2、、、 * */ public class Demo01GetThreadName { public static void main(String[] args) { // 创建Thread的子类对象 MyThread mt = new MyThread(); //调用start方法,开启新线程执行run方法 mt.start(); new MyThread().start(); //链式编程 这是获取主线程 System.out.println(Thread.currentThread().getName()); } }
设置线程的名称
了解
1 package com.learn.Thread04; 2 /* 3 * 设置线程的名称:(了解) 4 * 1、使用Thread类中的方法setName(名字) 5 * void setName(String name) 改变线程名称,使之与参数name相同。 6 * 2、创建一个带参数的构造方法,参数传递线程名称,调用父类的带参构造方法,把线程名称传递给父类Thread给子线程起名字 7 * Thread(String name)分配新的Thread对象 8 */ 9 public class MyThread extends Thread{ 10 11 @Override 12 public void run() { 13 //获取线程名称进行输出 14 System.out.println(Thread.currentThread().getName()); 15 } 16 public MyThread(){} 17 public MyThread(String name){ 18 super( name);//线程名称传递给父类Thread给子线程起名字 19 } 20 21 22 } 23 24 25 26 27 //测试类 28 29 public class Demo01SetThreadName { 30 31 public static void main(String[] args) { 32 // 开启多线程 33 MyThread mt = new MyThread(); 34 mt.setName("小强");//第一种方式设置线程名称 35 mt.start(); 36 37 new MyThread("旺财").start(); 38 39 } 40 41 }
Thread的sleep方法:
1 * Sleep方法 2 * public static void sleep(long millis);使用当前正在执行的线程以指定的毫秒数暂时停止执行 3 * 毫秒数结束后,线程继续执行+ 4 * 5 */ 6 public class Demo01Sleep { 7 8 public static void main(String[] args) { 9 // 模拟秒表 10 for(int i=1;i<=60;i++){ 11 System.out.println(i); 12 //使用Thread类的sleep方法让程序睡眠1秒钟 13 try { 14 Thread.sleep(1000); 15 } catch (InterruptedException e) { 16 // TODO Auto-generated catch block 17 e.printStackTrace(); 18 } 19 } 20 21 } 22 23 }
创建线程的第二种方式:
/* * 1、创建一个Runable接口的实现类 */ public class RunnableImpl implements Runnable{ //2、在实现类中重写Runnable接口中的run方法,设置线程任务 @Override public void run() { for(int i=0;i<20;i++){ System.out.println(Thread.currentThread().getName()+"-->"+i); } } } /* * 创建多线程程序的第二种方式:实现Runable接口 * java.lang.Runable * Runable:接口应该由那些打算通过某一线程执行其实列类来实现。类必须定义一个run的无参方法 * java.lang.Thread类的构造方法 * Thread(Runable target) 分配新的Thread 对象。 * Thread(Runable target,String name)分配新的Thread对象 * 实现步骤: * 1、创建一个Runable接口的实现类 * 2、在实现类中重写Runable接口中的run方法,设置线程任务 * 3、创建一个Runable接口的实现类对象 * 4、创建Thread类对象,构造方法中传递Runable接口的实现类对象 * 5、调用Thread类中的Star方法,开启新的线程执行run方法 * */ public class Demo01Runnable { public static void main (String[] args){ //3、创建一个Runable接口的实现类对象 RunnableImpl run = new RunnableImpl(); // 4、创建Thread类对象,构造方法中传递Runable接口的实现类对象 Thread t = new Thread(run); t.start(); for(int i=0;i<20;i++){ System.out.println(Thread.currentThread().getName()+"-->"+i); } } }
* 实现Runable接口创建多线程的好处:
1 * 实现Runable接口创建多线程的好处: 2 * 1、避免了单继承的局限性 3 * 一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类,就不能继承其他类 4 * 实现了Runnable接口,还可以继承其他类,实现其他接口 5 * 2、增强了程序的扩展性,降低了程序的耦合性(解耦) 6 * 实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离(解耦) 7 * 实现类中,重写了run方法,用来设置线程任务 8 * 创建Thread类对象调用star方法,用来开启新的线程 9 * 10 * 11 * 传递不同的实现类开启不同的任务
匿名内部类的方式:
1 /* 2 * 匿名内部类方式,实现线程的创建 3 * 4 * 匿名:没名字 5 * 6 * 内部类:写在其他类的内部 7 * 8 * 匿名内部类作用:简化代码 9 * 把子类继承父类,重写父类的方法创建子类对象合一部完成 10 * 把实现类实现接口,重写接口中的方法,创建实现类对象和成一部完成 11 * 匿名内部类的最终产物:子类/实现类对象,而这个类没有名字 12 * 13 * 格式: 14 * new 父类/接口(){ 15 * 重写父类/接口中的方法 16 * 17 * }; 18 * 19 */ 20 public class Demo01InnerClassThread { 21 public static void main(String[] args){ 22 //线程的父类是Thread 23 //new MyThread().star() 24 25 new Thread(){ 26 27 //重写run方法,设置线程任务 28 @Override 29 public void run() { 30 for(int i=0;i<20;i++){ 31 System.out.println(Thread.currentThread().getName()+"-->"+i); 32 } 33 } 34 35 }.start(); 36 //先后才能的接口Runnable 37 //Runnable r = new Runnable();//多肽 38 Runnable r=new Runnable(){ 39 40 @Override 41 public void run() { 42 // TODO Auto-generated method stub 43 for(int i=0;i<20;i++){ 44 System.out.println(Thread.currentThread().getName()+"-->"+"程序员"); 45 } 46 } 47 48 }; 49 Thread t = new Thread(r); 50 t.start(); 51 //简化接口的方式 52 new Thread(new Runnable(){ 53 54 @Override 55 public void run() { 56 // TODO Auto-generated method stub 57 for(int i=0;i<20;i++){ 58 System.out.println(Thread.currentThread().getName()+"-->"+"程序员"); 59 } 60 } 61 62 }).start(); 63 64 65 } 66 }