网站建设 唐山,58同城网站建设问题,深圳建设工程交易服务网中标,wordpress大前端5.2一、创建线程和使用线程方式1.1 继承Thread让线程类继承自Thread类#xff0c;然后重写run()#xff0c;把需要多线程调用的代码放到run()中。但是需要开启线程的时候不能调用run方法#xff0c;而是需要调用start()方法。/*** 本类用于演示第一种实现多线程的方式*/
class…一、创建线程和使用线程方式1.1 继承Thread 让线程类继承自Thread类然后重写run()把需要多线程调用的代码放到run()中。但是需要开启线程的时候不能调用run方法而是需要调用start()方法。/*** 本类用于演示第一种实现多线程的方式*/
class MyThread extends Thread{// 需要我们使用多进程运行的代码就写在run方法里Overridepublic void run() { for (int i 1; i 5; i) { System.out.println(Thread.currentThread().getName() 线程正在运行~~~~~~ i);}}
}
public class ThreadDemo01 extends Thread{public static void main(String[] args) {MyThread thread new MyThread();thread.start();for (int i 1; i 5; i) { System.out.println(Thread.currentThread().getName() 线程正在运行 i);}}
}运行结果(两个线程同时运行争抢cpu每次执行结果不固定)12.2 实现Runnable接口 需要我们创建的线程类实现Runnable接口。实现run方法把需要多线程调用的代码写在run方法中。由于Runnable接口中只有一个run方法所以不能直接调用start()。这个时候需要创建一个Thread类的对象来帮助我们开启线程。创建这个Thread类对象的时候需要将我们的线程类作为参数传递给Thread对象。/*** 本类用于演示第二种实现多线程的方式*/
class MyThread2 implements Runnable{// 需要我们使用多进程运行的代码就写在run方法里Overridepublic void run() { for (int i 1; i 5; i) { System.out.println(Thread.currentThread().getName() 线程正在运行~~~~~~ i);}}
}public class ThreadDemo02 {public static void main(String[] args) { MyThread2 myThread2 new MyThread2();// myThread2.run();// 由于Runable接口只有一个run方法所以实现Runnable接口的这种方式线程本身没有start方法。// 但是必须要调用start方法才能开启多线程所以需要创建Thread类的对象把我们的线程类作为参数传递给构造方法。Thread thread new Thread(myThread2);thread.start();for (int i 1; i 5; i) { System.out.println(Thread.currentThread().getName() 线程正在运行~~~~~~ i);} }
}运行结果(两个线程同时运行争抢cpu每次执行结果不固定)2.3 实现Callable接口 采用实现Callable接口实现多线程启动方式以上两种的方式不太一样下面就看一下怎样启动采用实现Callable接口的线程。 第一步定义一个类实现Callable接口并且指定call()返回值的类型。将业务逻辑写在call()方法中。 第二步创建FutureTask对象并将Callable对象传入FutureTask的构造方法中。 第三步实例化Thread对象并在构造方法中传入FurureTask对象。 第四步启动线程/*** 本类用于演示第三种实现多线程的方式*/
class MyCallable implements CallableString{Overridepublic String call() throws Exception {for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() 线程正在运行~~~~~ i);}return MyCallable接口执行完成;} }
public class ThreadDemo03 {public static void main(String[] args) throws Exception {// 1、创建FutureTask实例创建MyCallable实例FutureTaskString futureTask new FutureTask(new MyCallable());// 2、创建Thread实例来执行futureTaskThread thread new Thread(futureTask);thread.start();// 3、主线程for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() 线程正在运行~~~~~ i);}// 4、获取执行结果System.out.println(futureTask.get());}
}运行结果1.4 线程池 在一个应用程序中我们需要多次使用线程也就意味着我们需要多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存。而在Java中内存资源是及其宝贵的所以我们就提出了线程池的概念。 线程池Java中开辟出了一种管理线程的概念这个概念叫做线程池从概念以及应用场景中我们可以看出线程池的好处就是可以方便的管理线程也可以减少内存的消耗。 那么我们应该如何创建一个线程池那?Java中已经提供了创建线程池的一个类Executor而我们创建时一般使用它的子类ThreadPoolExecutor。 第一步使用Executors获取线程池对象 第二步通过线程池获取对象获取线程并执行Runable子类实例class MyThread4 implements Runnable{// 需要我们使用多进程运行的代码就写在run方法里Overridepublic void run() { for (int i 1; i 5; i) { System.out.println(Thread.currentThread().getName() 线程正在运行~~~~~~ i);}}
}
public class ThreadDemo04 {public static void main(String[] args) { // 第一步使用Executors获取线程池对象ExecutorService executorService Executors.newFixedThreadPool(10);// 第二步通过线程池获取对象获取线程并执行Runable实例executorService.execute(new MyThread4()); for (int i 1; i 5; i) { System.out.println(Thread.currentThread().getName() 线程正在运行~~~~~~ i);} }
} 运行结果二、总结2.1 实现接口和继承Thread类比较 1接口更适合多个相同的程序代码的线程去共享同一个资源。 实现Runnable接口这种方式可以把多线程之间相同的操作放到一个Runnable接口的run方法中实现然后可以通过多个thread来执行同一个Runnable实例。可以达到在一个地方开发多个地方使用做到代码的复用。 2接口可以避免Java中单继承的局限性。 Java的设计是单继承的设计如果采用继承Thread的方式实现多线程则不能继承其他的类就会错失继承很多父类方法。 3接口代码可以被多个线程共享代码和线程独立。 4线程池只能放入实现Runnable或Callable接口的线程不能直接放入继承Thread的类。 2.2 Runnable和Callable接口比较 A、相同点 1两者都是接口 2都可以用来编写多线程程序 3两者都需要调用Thread.start()启动线程 B、不同点 1实现Callable接口的线程能返回执行结果而实现Runnable接口的线程不能返回结果若需要用这个线程执行任务不需要控制则建议使用Runnable若需要动态监控任务则建议使用Callable。 2Callable接口的call()方法允许抛出异常而Runnable接口的run()方法不允许抛异常。 3实现Callable接口的线程可以调用Future.cancel取消执行而实现Runnable接口的线程不能。 注意点Callable接口支持返回执行结果此刻需要调用FutureTask.get()方法实现此方法会阻塞主线程直到获取“将来”结果不调用此方法时主线程不会阻塞。只能在不需要并发的地方调用get()方法。