有关java5以后的线程

创建线程的方式

方式一

继承于Thread类

/**  
 * 多线程的创建,方式一:继承于Thread类  
 * 1. 创建一个继承于Thread类的子类  
 * 2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中  
 * 3. 创建Thread类的子类的对象  
 * 4. 通过此对象调用start()  
 * <p>  
 * 例子:遍历100以内的所有的偶数  
 *  
 * @author shkstart  
 * @create 2019-02-13 上午 11:46  
 */  
//1. 创建一个继承于Thread类的子类 
class MyThread extends Thread {     
    //2. 重写Thread类的run()     
    @Override     
    public void run() {
    for (int i = 0; i < 100; i++) {
             if(i % 2 == 0){
                 System.out.println(Thread.currentThread().getName() + ":" + i);
             }
         }
     } }
   public class ThreadTest {
     public static void main(String[] args) {
         //3. 创建Thread类的子类的对象
         MyThread t1 = new MyThread();
         //4.通过此对象调用start():①启动当前线程 ② 调用当前线程的run()
         t1.start();
         //问题一:我们不能通过直接调用run()的方式启动线程。
         // t1.run();
         //问题二:再启动一个线程,遍历100以内的偶数。不可以还让已经start()的线程去执行。会报IllegalThreadStateException 
         //        t1.start();
         //我们需要重新创建一个线程的对象
         MyThread t2 = new MyThread();
         t2.start();
           //如下操作仍然是在main线程中执行的。
         for (int i = 0; i < 100; i++) {
             if(i % 2 == 0){
                 System.out.println(Thread.currentThread().getName() + ":" + i + "***********main()************");
             }
         }
     }
  } 

方式二

实现Runnable接口

/**
  * 创建多线程的方式二:实现Runnable接口
  * 1. 创建一个实现了Runnable接口的类
  * 2. 实现类去实现Runnable中的抽象方法:run()
  * 3. 创建实现类的对象
  * 4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
  * 5. 通过Thread类的对象调用start()  *  *  * 比较创建线程的两种方式。
  * 开发中:优先选择:实现Runnable接口的方式
  * 原因:1. 实现的方式没有类的单继承性的局限性
  *      2. 实现的方式更适合来处理多个线程有共享数据的情况。
  *
  * 联系:public class Thread implements Runnable
  * 相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中。
  *
  * @author shkstart
  * @create 2019-02-13 下午 4:34
  */
//1. 创建一个实现了Runnable接口的类
class MThread implements Runnable{
      //2. 实现类去实现Runnable中的抽象方法:run()
     @Override
     public void run() {
         for (int i = 0; i < 100; i++) {
             if(i % 2 == 0){
                 System.out.println(Thread.currentThread().getName() + ":" + i);
             }
          }
     }
 }   
public class ThreadTest1 {
     public static void main(String[] args) {
         //3. 创建实现类的对象
         MThread mThread = new MThread();
         //4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
         Thread t1 = new Thread(mThread);
         t1.setName("线程1");
         //5. 通过Thread类的对象调用start():① 启动线程 ②调用当前线程的run()-->调用了Runnable类型的target的run()
         t1.start();
         //再启动一个线程,遍历100以内的偶数
         Thread t2 = new Thread(mThread);
         t2.setName("线程2");
         t2.start();
     }
  }

方式一与方式二比较推荐使用方式二,方式二实现的方式没有类的单继承性的局限性,实现的方式更适合来处理多个线程有共享数据的情况。


测试Thread中的常用方法:

/**
  * 测试Thread中的常用方法:
  * 1. start():启动当前线程;调用当前线程的run()
  * 2. run(): 通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
  * 3. currentThread():静态方法,返回执行当前代码的线程
  * 4. getName():获取当前线程的名字
  * 5. setName():设置当前线程的名字
  * 6. yield():释放当前cpu的执行权
  * 7. join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才
  *           结束阻塞状态。
  * 8. stop():已过时。当执行此方法时,强制结束当前线程。
  * 9. sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒。在指定的millitime毫秒时间内,当前
  *                          线程是阻塞状态。
  * 10. isAlive():判断当前线程是否存活
  *
  *
  * 线程的优先级:
  * 1.
  * MAX_PRIORITY:10
  * MIN _PRIORITY:1
  * NORM_PRIORITY:5  -->默认优先级
  * 2.如何获取和设置当前线程的优先级:
  *   getPriority():获取线程的优先级
  *   setPriority(int p):设置线程的优先级
  *
  *   说明:高优先级的线程要抢占低优先级线程cpu的执行权。但是只是从概率上讲,高优先级的线程高概率的情况下
  *   被执行。并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行。
  *
  *
  * @author shkstart
  * @create 2019-02-13 下午 2:26
  */ class HelloThread extends Thread{
     @Override
     public void run() {
         for (int i = 0; i < 100; i++) {
             if(i % 2 == 0){
  //                try {
 //                    sleep(10);
 //                } catch (InterruptedException e) {
 //                    e.printStackTrace();
 //                }
                  System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
             }
  //            if(i % 20 == 0){
 //                yield();
 //            }
          }
      }
      public HelloThread(String name){
         super(name);
     }
 }
   public class ThreadMethodTest {
     public static void main(String[] args) {
          HelloThread h1 = new HelloThread("Thread:1");
  //        h1.setName("线程一");
         //设置分线程的优先级
         h1.setPriority(Thread.MAX_PRIORITY);
         h1.start();
          //给主线程命名
         Thread.currentThread().setName("主线程");
         Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
          for (int i = 0; i < 100; i++) {
             if(i % 2 == 0){
                 System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
             }
  //            if(i == 20){
 //                try {
 //                    h1.join();
 //                } catch (InterruptedException e) {
 //                    e.printStackTrace();
 //                }
 //            }
          }
  //        System.out.println(h1.isAlive());
      }
 }

创建线程的方式三:

实现Callable接口。 --- JDK 5.0新增

 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.FutureTask;
  /**
  * 创建线程的方式三:实现Callable接口。 --- JDK 5.0新增
  *
  *
  * 如何理解实现Callable接口的方式创建多线程比实现Runnable接口创建多线程方式强大?
  * 1. call()可以有返回值的。
  * 2. call()可以抛出异常,被外面的操作捕获,获取异常的信息
  * 3. Callable是支持泛型的
  *
  * @author shkstart
  * @create 2019-02-15 下午 6:01
  */
 //1.创建一个实现Callable的实现类
 class NumThread implements Callable{
     //2.实现call方法,将此线程需要执行的操作声明在call()中
     @Override
     public Object call() throws Exception {
         int sum = 0;
         for (int i = 1; i <= 100; i++) {
             if(i % 2 == 0){
                 System.out.println(i);
                 sum += i;
             }
         }
         return sum;
     }
 }
   public class ThreadNew {
     public static void main(String[] args) {
         //3.创建Callable接口实现类的对象
         NumThread numThread = new NumThread();
         //4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
         FutureTask futureTask = new FutureTask(numThread);
         //5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
         new Thread(futureTask).start();
          try {
             //6.获取Callable中call方法的返回值
             //get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。
             Object sum = futureTask.get();
             System.out.println("总和为:" + sum);
         } catch (InterruptedException e) {
             e.printStackTrace();
         } catch (ExecutionException e) {
             e.printStackTrace();
         }
     }
  }

方式四

使用线程池

 /**
  * 创建线程的方式四:使用线程池
  *
  * 好处:
  * 1.提高响应速度(减少了创建新线程的时间)
  * 2.降低资源消耗(重复利用线程池中线程,不需要每次都创建)
  * 3.便于线程管理
  *      corePoolSize:核心池的大小
  *      maximumPoolSize:最大线程数
  *      keepAliveTime:线程没有任务时最多保持多长时间后会终止
  *
  *
  * 面试题:创建多线程有几种方式?四种!
  * @author shkstart
  * @create 2019-02-15 下午 6:30
  */
  class NumberThread 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 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);
             }
         }
     }
 }
  public class ThreadPool {
      public static void main(String[] args) {
         //1. 提供指定线程数量的线程池
         ExecutorService service = Executors.newFixedThreadPool(10);
         ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
         //设置线程池的属性
 //        System.out.println(service.getClass());
 //        service1.setCorePoolSize(15);
 //        service1.setKeepAliveTime();
           //2.执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象
         service.execute(new NumberThread());//适合适用于Runnable
         service.execute(new NumberThread1());//适合适用于Runnable
  //        service.submit(Callable callable);//适合使用于Callable
         //3.关闭连接池
         service.shutdown();
     }
  }
posted @ 2019-11-25 13:34  IT终结者  阅读(306)  评论(0编辑  收藏  举报