1.多线程的实现方式
创建新执行线程有3种方法。
l 一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。创建对象,开启线程。run方法相当于其他线程的main方法。
l 另一种方法是声明一个实现 Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。
l 第三种方法是实现Callable接口的类。
1.1创建线程方式一继承Thread类
创建线程的步骤:
1 、定义一个类继承Thread。
2 、重写run方法。
3 、创建子类对象,就是创建线程对象。
4 、调用start方法,开启线程并让线程执行,同时还会告诉jvm去调用run方法。
实现如下:
public class MyThread extends Thread { //定义指定线程名称的构造方法 public MyThread(String name) { //调用父类的String参数的构造方法,指定线程的名称 super(name); } /** * 重写run方法,完成该线程执行的逻辑 */ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(getName()+":正在执行!"+i); } } }
public class Demo1 { public static void main(String[] args) { //创建自定义线程对象 MyThread mt = new MyThread("新的线程!"); //开启新线程 mt.start(); //在主方法中执行for循环 for (int i = 0; i < 10; i++) { System.out.println("main线程!"+i); } } }
1.2创建线程方式—实现Runnable接口
1、定义类实现Runnable接口。
2、覆盖接口中的run方法。
3、创建Thread类的对象
4、将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
5、调用Thread类的start方法开启线程。
实现如下:
public class MyRunnable implements Runnable{ //定义线程要执行的run方法逻辑 @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("我的线程:正在执行!"+i); } } }
public class Demo2 { public static void main(String[] args) { //创建线程执行目标类对象 Runnable runn = new MyRunnable(); //将Runnable接口的子类对象作为参数传递给Thread类的构造函数 Thread thread = new Thread(runn); Thread thread2 = new Thread(runn); //开启线程 thread.start(); thread2.start(); for (int i = 0; i < 10; i++) { System.out.println("main线程:正在执行!"+i); } } }
1.3创建线程方式—实现Callable接口
1、定义类实现Callable接口。
2、覆盖接口中的call方法。
3、借助FutureTask执行(将Callable接口的子类对象传递给新建的FutureTask对象)。
4、将创建的FutureTask对象传递给新建的Thread对象。
5、调用Thread类的start方法开启线程。
或者同样执行第1、2步,之后借助线程池执行(创建线程池并提交一个Callable任务)
public class MyCallable implements Callable<Integer>{ @Override public Integer call() throws Exception { System.out.println("线程在进行计算"); Thread.sleep(3000); int sum = 0; for(int i=0;i<100;i++) sum += i; return sum; } }
public class Demo3 { public static void main(String[] args) { method1(); method2(); } /** * 借助FutureTask执行 */ public static void method1() { Callable<Integer> callable = new MyCallable(); FutureTask<Integer> future = new FutureTask<Integer>(callable); new Thread(future).start(); try { Thread.sleep(5000); System.out.println(future.get()); } catch (Exception e) { e.printStackTrace(); } } /** * 借助线程池来运行 */ public static void method2() { Callable<Integer> callable = new MyCallable(); ExecutorService threadPool = Executors.newSingleThreadExecutor(); Future<Integer> future = threadPool.submit(callable); try { Thread.sleep(5000);// 可能做一些事情 System.out.println(future.get()); } catch (Exception e) { e.printStackTrace(); } } }
1.4线程的匿名内部类使用
使用线程的内匿名内部类方式,可以方便的实现每个线程执行不同的线程任务操作。
l 方式1:创建线程对象时,直接重写Thread类中的run方法
l 方式2:使用匿名内部类的方式实现Runnable接口,重新Runnable接口中的run方法
/* * 使用匿名内部类,实现多线程程序 * 前提:继承或者接口实现 * new 父类或者接口(){ * 重写抽象方法 * } */ public class Demo4 { public static void main(String[] args) { // 继承方式 XXX extends Thread{ public void run(){}} new Thread(){ public void run(){ for (int i = 0; i < 10; i++) System.out.println("###"); } }.start(); // 实现接口方式 XXX implements Runnable{public void run(){}} Runnable run = new Runnable() { public void run() { for (int i = 0; i < 10; i++) System.out.println("***"); } }; new Thread(run).start(); new Thread(new Runnable() { public void run() { for (int i = 0; i < 10; i++) System.out.println("$$$"); } }).start(); } }