java多线程与线程池(一):多线程概述
引用自https://www.runoob.com/java/java-multithreading.html Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。 这里定义和线程相关的另一个术语 - 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有的非守护线程都结束运行后才能结束。 多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。 一个线程也有他的生命周期:
其实这与操作系统中的概念,没有太大的区别。 下面来说说如何在java中创建一个线程: 1)通过继承Thread类: public class MyThread extends Thread{ private int i=0; public MyThread(){} @Override public synchronized void start() { super.start(); } @Override public void run() { for (i=0;i<3;i++){ System.out.println(Thread.currentThread().getName() + " " + i); } } } public class TestThread { public static void main(String[] args) { for(int i = 0;i<5;i++){ System.out.println(Thread.currentThread().getName() + i); if(i == 3){ Thread thread1 = new MyThread(); Thread thread2 = new MyThread(); thread1.start(); thread2.start(); } } } } 运行结果如下: 如果在if里加上sleep(100),那么main4就会在最下面输出。这里还有一点要注意的是,在这种实现多线程方法下,调用start()即会调用对应线程的run(),无需start()后再调用run()。如果再调用run(),就会变成这样: 图中带空格的main i,就是因为main中直接调用线程类的run()方法导致的,因为是main直接调用线程的run()方法,所以currentThread.getName()结果就是main(下面线程的结果我没有截进来) 2)通过实现Runnable接口来创建线程 public class MyThread implements Runnable{ Thread thread; MyThread(){} public void start(){ if(thread == null){ thread = new Thread(this); thread.start(); } } @Override public void run() { int i; for (i=0;i<3;i++){ System.out.println(Thread.currentThread().getName() + " " + i); } } } public class TestThread { public static void main(String[] args) { for(int i = 0;i<5;i++){ System.out.println(Thread.currentThread().getName() + i); if(i == 3){ MyThread thread1 = new MyThread(); MyThread thread2 = new MyThread(); thread1.start(); thread2.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } } 这种方法下就需要自己在线程类下实例化Thread,实例化时目标选为this,再调用start()方法,之后再main里执行start()时,被启动的线程便会自动调用其run()方法。 3)通过Callable和Future创建线程 public class TestThread implements Callable<Integer> { public static void main(String[] args) { TestThread thread = new TestThread(); FutureTask<Integer> futureTask = new FutureTask<>(thread); for(int i = 0;i<5;i++){ System.out.println(Thread.currentThread().getName() + i); if(i==2){ new Thread(futureTask).start(); } } try { System.out.println("子线程的返回值:"+ futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } @Override public Integer call() throws Exception { int i = 0; for(;i<3;i++){ System.out.println(Thread.currentThread().getName() + " " + i); } return i; } } 说实话这种方法我觉得异常的繁琐,但是使用他的优点是线程结束后可以有返回值,想必也有它独特的用处,先了解着。 创建线程的三种方式的对比:
之后的内容:
多线程使用时的注意事项: 有效利用多线程的关键是理解程序是并发执行而不是串行执行的。例如:程序中有两个子系统需要并发执行,这时候就需要利用多线程编程。 通过对多线程的使用,可以编写出非常高效的程序。不过请注意,如果你创建太多的线程,程序执行的效率实际上是降低了,而不是提升了。 请记住,上下文的切换开销也很重要,如果你创建了太多的线程,CPU 花费在上下文的切换的时间将多于执行程序的时间! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |