学习总结:Java线程的概念以及使用方式
线程
概念
每一个程序都是静态的,是指令和数据的有序集合。 执行程序的时候,进程就是执行程序的一次过程,是系统资源分配的单位。 一个进程中至少包含一个线程,线程也是CPU调度和执行的单位
举个例子,视频播放器就是一个程序。 我们在电脑上打开视频播放器之后,在任务管理器可以看到:视频播放器.exe,这个“视频播放器.exe”就是一个进程。 随后我们播放电影,我们可以听到声音、看到画面,这两个就是线程,一个线程负责播放声音,一个线程负责显示画面。
使用方式
一、继承Thread类
1、新建类继承Thread 2、重写run()方法 3、实例化之后调用start()方法。 虽然简单,但是Java的类没有多继承,这样不利于面向对象编程。
public class Test1 { public static void main(String[] args) { //实例化后调用start() MyThread1 m1 = new MyThread1(); m1.start(); } } //继承Thread类 class MyThread1 extends Thread{ @Override public void run() { //业务逻辑 } }
二、实现Runnable接口
1、新建类实现Runnable接口 2、重写run()方法 3、创建实现类对象与代理类对象,并把实现类对象作为参数传入代理类对象 4、调用start()方法 解决了继承的问题
public class Test1 { public static void main(String[] args) { //创建实现类对象 MyThread2 m2 = new MyThread2(); //创建代理类对象,并把实现类对象传入 Thread thread = new Thread(m2); //调用 thread.start(); } } //实现Runnable接口 class MyThread2 implements Runnable{ @Override public void run() { //业务逻辑 } }
三、实现Callable接口
1、新建类实现Callable接口 2、重写call()方法 3、使用线程池 可以定义返回值类型,并且可以抛出异常,但是步骤比较繁琐
public class Test1 { public static void main(String[] args) throws ExecutionException, InterruptedException { //实例化 MyThread3 m3 = new MyThread3(); //开启线程池服务 ExecutorService es = Executors.newFixedThreadPool(3); //提交执行 Future<Boolean> s = es.submit(m3); //获得结果 boolean result = s.get(); //关闭服务 es.shutdown(); } } //实现Callable接口 class MyThread3 implements Callable<Boolean>{ @Override public Boolean call() { return true; } }
总结
1、一般使用实现Runnable接口方式较多。 2、主要是为了运用多线程,优化性能。 3、多线程的本质其实是CPU通过调度,不断地切换线程执行,同一时间一个CPU只会执行一条线程,所以实际上是线程的交替执行。 4、线程是独立的,需要添加并发控制,防止同一时间两个线程抢夺同一份资源。 5、线程的调度是由操作系统决定的,无法人为干预。 6、现成的创建会产生开销,并且内存控制不当就会导致数据不一致。 7、调用start()方法才是真正意义上的启动线程,很快就会出现异步操作;调用run()方法启动则是依然同步执行操作。