实现线程的两种方式
一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。创建对象,开启线程。run方法相当于其他线程的main方法。
另一种方法是声明一个实现 Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。
//继承Thread线程 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(Thread.currentThread().getName()+":正在执行!"+i); } } 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); } }
public class MyRunnable implements Runnable { private String s=null; public MyRunnable(String s) { this.s=s; } @Override public void run() { // TODO Auto-generated method stub for(int i=10;i>0;i--) { System.out.println(s+":"+i); } } public static void main(String[] args) { //创建自定义Runnable对象 Runnable myRunnable = new MyRunnable("我的Runnable线程"); //把Runnable添加到线程 Thread t = new Thread(myRunnable); t.start(); //在主方法中执行for循环 for (int i = 0; i < 10; i++) { System.out.println("main线程!"+i); } }
第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。实现runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。Runnable接口对线程对象和线程任务进行解耦。
匿名方式创建线程
public static void main(String[] args) { /** * 创建线程的两种种匿名方式 */ //方式1 new Thread() { public void run() { for(int i=0;i<10;i++) { System.out.println(i); } } }.start(); //方式2 Runnable r = new Runnable() { public void run() { for(int i=0;i<10;i++) { System.out.println(i); } } }; new Thread(r).start(); } }
线程池方式--Runnable接口
Executors:线程池创建工厂类
public static ExecutorService newFixedThreadPool(int nThreads):返回线程池对象
ExecutorService:线程池类
Future<?> submit(Runnable task):获取线程池中的某一个线程对象,并执行
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("我需要一个教练"); try { Thread.sleep(2000); }catch(Exception e) { e.getLocalizedMessage(); } System.out.println("教练来了:"+Thread.currentThread().getName()); System.out.println("教练走了"); } } public static void main(String[] args) { //创建一个线程池对象 ExecutorService service=Executors.newFixedThreadPool(5); MyRunnable r = new MyRunnable(); //从线程池中获取线程,再调用run()方法 service.submit(r); service.submit(r); service.submit(r); service.submit(r); service.submit(r); service.shutdown(); }
使用线程池方式—Callable接口
Callable接口:与Runnable接口功能相似,用来指定线程的任务。其中的call()方法,用来返回线程任务执行完毕后的结果,call方法可抛出异常。
ExecutorService:线程池类
<T> Future<T> submit(Callable<T> task):获取线程池中的某一个线程对象,并执行线程中的call()方法
Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用
package thread; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class ThreadPoolDemo { public static void main(String[] args) throws InterruptedException, ExecutionException { //创建一个线程池对象 ExecutorService service=Executors.newFixedThreadPool(5); MyCallable c = new MyCallable(10,9); Future<Object> f=service.submit(c); Integer i=(Integer)f.get(); System.out.println(i); Future<Object> f2=service.submit(c); Future<Object> f3=service.submit(c); Future<Object> f4=service.submit(c); Future<Object> f5=service.submit(c); service.shutdown(); for(int b=0;b<5;b++) { System.out.println(Thread.currentThread().getName()+"..."+"教练被我抢了"+b); } } } package thread; import java.util.concurrent.Callable; public class MyCallable implements Callable<Object> { private int x; private int y; public MyCallable() { super(); } public MyCallable(int x,int y) { this.x=x; this.y=y; } @Override public Object call() throws Exception { System.out.println("我需要一个教练"); Thread.sleep(2000); System.out.println("教练来了:"+Thread.currentThread().getName()); System.out.println("教练走了"); return x+y; } }