创建多线程有四种的方式
1、继承Thread类
步骤:
1、创建一个继承Thread的子类
2、在子类中重写run()方法。此线程执行的操作声明在run()方法中。
3、创建子类的对象
4、调用Start()方法。start()的作用是启动线程并执行run().
代码实现如下:
//打印10以内的偶数 class MyThread extends Thread{ @Override public void run() { for (int i=0;i<10;i++){ if (i%2==0) { System.out.println(Thread.currentThread().getName()+":"+i); } } } } //打印10以内的奇数 class MyThread1 extends Thread{ @Override public void run() { for (int i=0;i<10;i++){ if (i%2!=0) { System.out.println(Thread.currentThread().getName()+":"+i); } } } } public class ThreadTest { public static void main(String[] args) { MyThread myThread = new MyThread(); // 调用start():①启动当前线程②调用当前线程的run()方法 myThread.start();
MyThread1 myThread1 = new MyThread1(); myThread1.start(); for (int i=0;i<10;i++){ if (i%2==0) { System.out.println(Thread.currentThread().getName()+":"+i); } } System.out.println("hellow"); } }
输出结果如下:
main:0 main:2 main:4 main:6 main:8 hellow Thread-0:0 Thread-0:2 Thread-0:4 Thread-0:6 Thread-0:8 Thread-1:1 Thread-1:3 Thread-1:5
2、实现Runnable接口
步骤如下:
1、创建实现Runnable接口的实现类
2、实现类中重写run()方法。
3、创建实现类的对象
4、将实现类的对象作为参数传递到Thread构造器中,创建一个Thrad类的对象
5、通过Thread对象调用start()方法
代码实现如下:
class MyThread2 implements Runnable{ @Override public void run() { for (int i =0;i<10;i++) { if (i%2==0){ System.out.println(Thread.currentThread().getName()+":"+i); } } } } class MyThread3 implements Runnable{ @Override public void run() { for (int i =0;i<10;i++) { if (i%2!=0){ System.out.println(Thread.currentThread().getName()+":"+i); } } } }
public class ThreadTest1 { public static void main(String[] args) { MyThread2 myThread2 = new MyThread2(); Thread thread2 = new Thread(myThread2); //setName():为线程赋名 thread2.setName("线程一"); thread2.start(); MyThread3 myThread3 = new MyThread3(); Thread thread3 = new Thread(myThread3); thread3.setName("线程二"); thread3.start(); Thread.currentThread().setName("主线程"); for (int i =0;i<10;i++) { if (i%2==0){ System.out.println(Thread.currentThread().getName()+":"+i); } } } }
运行结果如下:
主线程:0 主线程:2 主线程:4 主线程:6 主线程:8 线程一:0 线程一:2 线程一:4 线程一:6 线程一:8 线程二:1 线程二:3 线程二:5 线程二:7 线程二:9
使用实现Runnable接口对比继承Thread类:
源码如下:
public class Thread implements Runnable { /* Make sure registerNatives is the first thing <clinit> does. */ private static native void registerNatives(); static { registerNatives(); }
3、实现Callable接口
步骤如下:
1、创建一个实现Callable接口的实现类
2、实现类重写call()方法。此线程执行的操作声明在该方法中。
3、创建实现类的对象
4、将实现类的对象作为参数传递到FutureTask的构造器中,创建FutureTask对象
5、将FutureTask对象作为参数传递到Thread构造器中,创建Thread对象
6、通过Thread对象调用start()方法
7、也可以通过get()方法得到call()方法的返回值
代码实现如下:
//创建实现类 class NumberThread implements Callable { @Override public Object call() throws Exception { int sum = 0; //线程需要进行的操作 for (int i = 0; i <= 10; i++) { if (i%2==0){ System.out.println(Thread.currentThread().getName()+":"+i); sum+=i; } } return sum; } }
public class ThreadTest3 { public static void main(String[] args) { //创建实现类的对象 NumberThread numberThread = new NumberThread(); //将实现类的对象作为参数传递到FutureTask构造器中 FutureTask futureTask = new FutureTask(numberThread); //传递到Thread中 Thread thread = new Thread(futureTask); thread.setName("callable线程"); thread.start(); //获取返回值 try { Object sum = futureTask.get(); System.out.println("总和为"+sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } Thread.currentThread().setName("主线程"); for (int i = 0; i <10 ; i++) { if(i%2!=0){ System.out.println(Thread.currentThread().getName()+":"+i); } } } }
运行结果如下:
callable线程:0 callable线程:2 callable线程:4 callable线程:6 callable线程:8 callable线程:10 总和为30 主线程:1 主线程:3 主线程:5 主线程:7 主线程:9
实现Callable接口的方式与实现Runnable接口的比较:
4、线程池
1、实现接口或者继承类的器中一种
2、指定线程的数量
3、执行指定线程的操作
4、关闭线程
代码如下:
class NumberThread1 implements Runnable{ @Override public void run() { for (int i = 0; i <= 100; i++) { if (i%2==0){ System.out.println(Thread.currentThread().getName()+":"+i); } } } } class NumberThread2 implements Runnable{ @Override public void run() { for (int i = 0; i <= 100; i++) { if (i%2!=0){ System.out.println(Thread.currentThread().getName()+":"+i); } } } }
public class ThreadTest4 { public static void main(String[] args) { //①指定线程数量 ExecutorService service = Executors.newFixedThreadPool(10); //②执行 service.execute(new NumberThread1());//适用于runnable接口 //service.submit(Callable callable); 适用于Callable接口 service.execute(new NumberThread2()); //③关闭 service.shutdown(); } }
使用线程池的好处:
5、关于线程还有一些方法的使用
class HelloThread extends Thread{ @Override public void run() { for (int i = 0; i <100 ; i++) { //sleep():线程睡眠,在时间1000ms期间是阻塞的 try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if(i%2==0){ System.out.println(getName()+":"+getPriority()+":"+i); } //yield():释放当前线程的cpu if(i%20==0){ yield(); } } } }
public class ThreadMethodTest { public static void main(String[] args) { HelloThread h1 = new HelloThread(); //setName():给分线程赋予名称 h1.setName("线程1"); //setPriority():给分线程赋予优先级 //MAX_PRIORITY:10 最高级 //MIN _PRIORITY:1 最低级 //NORM_PRIORITY:5 -->默认优先级 //注意:高优先级的线程要抢占低优先级线程cpu的执行权。但是只是从概率上讲,高优先级的线程高概率的情况下 //被执行。并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行。 h1.setPriority(Thread.MIN_PRIORITY); h1.start(); //给主线程赋予名称 Thread.currentThread().setName("主线程"); //给主线程赋予优先级 Thread.currentThread().setPriority(Thread.MAX_PRIORITY ); for (int i = 0; i < 100; i++) { if (i%2==0){ //主线程的当前名字 System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority()+":"+i); } //join():线程阻塞 当前线程在i=20时,线程阻塞 等待下一个线程完成 在重新运行 if (i==20){ try { h1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
原文:https://www.cnblogs.com/Y-xiaojian/p/11905762.html