码迷,mamicode.com
首页 > 编程语言 > 详细

java多线程的实现

时间:2018-07-12 20:13:38      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:throwable   fence   线程池   mat   fun   executors   dex   ide   应用   

线程和进程之间的关系

? 线程时在进程基础之上创建并使用的更小的程序单元,所以线程依赖于进行的支持。线程的启动速度要比进程快上很多,高并发处理的时候,线程的性能要高于进程

多线程实现

任何情况下,只要定义了多线程,那么多线程的启动永远只有一种方案:Thread类的start()方法

不要调用Thread类话或者Runnable对象的run方法。直接调用run方法,只会执行同一个线程中的任务,而不会启动新的线程。应该调用Thread.start方法,这个run方法将创建执行run方法的新线程。(摘自java核心技术)

继承Thread类

? 定义多线程主体类,继承Thread类,只有重写run()方法,多线程要执行的功能应该在run()方法中定义

? start()方法最终执行的时run()方法中的功能,但是如果直接使用run()方法的话,将不能开启多线程(线程顺序执行,而不是交替执行)

public class MyThread extends Thread {
   @Override
   public void run() {
       //多线程功能定义
  }
}
?

查看Thread的start()源码

/**
    * @exception IllegalThreadStateException if the thread was already
    *               started.
    * @see       #run()
    * @see       #stop()
    */
   public synchronized void start() {
 
       if (threadStatus != 0)
           throw new IllegalThreadStateException();

   
       group.add(this);
?
       boolean started = false;
       try {
           start0();
           started = true;
      } finally {
           try {
               if (!started) {
                   group.threadStartFailed(this);
              }
          } catch (Throwable ignore) {
             
          }
      }
  }

每个线程类的对象只允许启动一次,如果重复启动,会报IllegalThreadStateException异常

技术分享图片

实现Runnable接口

? Runnable接口源码

@FunctionalInterface
public interface Runnable {
   /**
    *
    * @see     java.lang.Thread#run()
    */
   public abstract void run();
}

为函数式编程,可以使用jdk1.8的lamda表达式

传统实现

public class MyThread1 implements Runnable {
?
   /**
    * title
    */
   private String title;
?
   public MyThread1(String title) {
       this.title = title;
  }
?
   @Override
   public void run() {
       for (int i = 0; i < 10; i++) {
           System.out.println(this.title + "运行,i=" + i);
      }
  }
}

lamda表达式

       Runnable runnable = ()->{
           for (int i = 0; i < 10; i++) {
               System.out.println("线程开始运行");
          }
      };
       new Thread(runnable).start();

启动:

       final MyThread1 thread1 = new MyThread1("线程A");
       final MyThread1 thread2 = new MyThread1("线程B");
       final MyThread1 thread3 = new MyThread1("线程C");
?
       new Thread(thread1).start();
       new Thread(thread2).start();
       new Thread(thread3).start();

WARNING:

线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

说明:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决系统资源不足的问题。如果不适用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者"过度切换的问题"。

应该将要并行运行的任务与运行机制解耦合。如果有很多任务,要为每个任务创建一个独立的线程所付出的代价太大了,可以使用线程池来解决这个问题。(摘自java核心技术)

线程池创建线程示例:

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
       ExecutorService singleThreadPool = new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new
               LinkedBlockingDeque<Runnable>(1024),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());
       singleThreadPool.execute(()-> System.out.println(Thread.currentThread().getName()));
       singleThreadPool.shutdown();

Thread和Runnable的关系

技术分享图片

多线程的设计之中,使用了代理设计模式的结构,用户自定义的线程主体知识负责项目核心功能的实现,而所有的辅助实现全部交由Thread类来实现

多线程开发的本质上是在于多个线程可以进行同一资源的抢占,那么Thread主要描述的是线程,而资源的描述是通过Runnable完成的。

技术分享图片

 

多线程资源访问实现卖票程序

public class MyThread implements Runnable {
?
   private int ticket = 5;
?
   @Override
   public void run() {
       //多线程功能定义
       for (int i = 0; i < 100; i++) {
           if (this.ticket > 0) {
               System.out.println("卖票,ticket=" + this.ticket--);
          }
      }
  }
}
public class ThreadDemo {
   public static void main(String[] args) {
       MyThread mt = new MyThread();
       new Thread(mt).start();
       new Thread(mt).start();
       new Thread(mt).start();
  }
}

Callable实现多线程

使用Callable实现多线程的好处在于在线程执行完毕之后可以获取一个返回值,同时支持泛型

技术分享图片

范例:使用Callable实现多线程处理

public class MyThread implements Callable<String > {
?
   @Override
   public String call() throws Exception {
       for (int i = 0; i < 10; i++) {
           System.out.println("********* 线程执行、i = "+i);
      }
       return "线程执行完毕";
  }
}
?
public class ThreadDemo {
   public static void main(String[] args) throws ExecutionException, InterruptedException {
       FutureTask<String> task = new FutureTask<>(new MyThread());
       new Thread(task).start();
       System.out.println("【线程返回的数据】" + task.get());
  }
}

线程运行状态

? 对于多线程的开发而言,编写程序的过程之中总是按照:定义线程主体类,而后通过Thread类进行线程的启动,但不以为者你调用了start()方法,线程就已经开发启动了,因为整体的线程处理有自己的一套运行的状态。

技术分享图片

 

java多线程的实现

标签:throwable   fence   线程池   mat   fun   executors   dex   ide   应用   

原文地址:https://www.cnblogs.com/keepongjl/p/9301040.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!