多线程
三、多线程
3.1 基本概念
线程是程序在执行过程中,能够执行程序代码的一个执行单元。
4种状态:运行、就绪、挂起【等待】、结束;
为什么使用多线程?
多线程的使用为程序的开发而开发,能够带来很多便利。比如:
(1)减少程序的响应时间。
(2)相比于进程,线程的创建和切换的开销更小。
(3)现代计算机【多核】都能够执行多线程的能力,如果使用单线程,无法重复计算利用计算机的资源,造成资源的巨大浪费。多核计算机使用多线程能够提高CPU的利用率。
(4)简化程序结构,便于理解和维护。
同步与异步
实现同步的方式:
(1)利用同步代码块来实现同步。
(2)利用同步方法来实现同步。
异步与非阻塞相似,当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回,就应该使用异步编程,异步能够提高程序的效率。
创建多线程的常见方式
继承Thread
class MyThread extends Thread { @Override public void run() { // 线程执行的代码 } } // 创建并启动新线程 MyThread thread = new MyThread(); thread.start();
Runnable接口实现类
class MyRunnable implements Runnable { @Override public void run() { // 线程执行的代码 } } // 创建实现了Runnable接口的对象 MyRunnable runnable = new MyRunnable(); // 创建并启动新线程 Thread thread = new Thread(runnable); thread.start();
使用匿名内部类
Thread thread = new Thread() { @Override public void run() { // 线程执行的代码 } }; // 启动新线程 thread.start();
Lambda表达式
Thread thread = new Thread(() -> { // 线程执行的代码 }); // 启动新线程 thread.start();
实现Callable接口
//实现Callable class Mythreadd03 implements Callable<Integer>{ // 重写call方法 @Override public Integer call() throws Exception { System.out.println("实现Callable接口"); return 1; } } FutureTask<Integer> futuretask = new FutureTask<Integer>(new Mythreadd03()); // 调用Thread启动的start()方法 new Thread(futuretask).start(); // 获取返回值 System.out.println(futuretask.get());
【------------------------------------------------------】
实现同步机制的方法(3种):
1.synchronized
。。。。
。。。
2.wait()方法与notify()方法
3.Lock
利用Thread.wait()同步线程,可以设置超时时间。
终止线程的方法有哪些?
可以使用stop()方法与suspend()方法来终止线程的执行。
synchronized 【ˈsɪŋkrənaɪzd】和Lock有什么异同?
两种锁机制来实现对某个共享资源的同步:synchronized和Lock。其中,synchronized使用Object对象本身的notify、wait、notityAll调度机制。而Lock可以使用Condition进行线程之间的调度,完成synchronized实现的所有功能。
区别在于:
(1)用法不一样。
synchronized加在特定代码块中,括号中表示需要锁的对象。
(2)性能不一样。(3)锁机制不一样。
当一个线程进入一个对象的一个synchronized()方法后,其他线程是否可进入此对象的其他方法?
答:当一个线程进入一个对象的一个synchronized方法后,其他线程是否可进入此对象的其他方法取决于方法本身,如果该方法是非synchronized()方法,那么是可以访问的。
什么是守护线程?
Java提供了两种线程:守护线程与用户线程。守护线程又被称为“服务线程”“精灵线程”或者“后台线程”,是指在程序运行时在后台提供一种通用服务的线程,这种线程并不属于程序中不可或缺的部分。
join()方法的作用是什么?
join()方法的作用是让调用该方法的线程在执行完run()方法后,在执行join方法后面的代码。简单点说,就是将两个线程合并,用于实现同步功能。具体而言,可以通过线程A的join()方法来等待线程A的结束,或者使用线程A的join(2000)方法来等待线程A的结束,但最多只等2s。