好久没更新,小编感冒了好几天,今天给大家带来一篇代码块的拆解吧。
同样,咱们还是先列出掌握知识需要解决的几个核心问题:
一,代码块是什么,有什么细分,他们的区别是,既然在类之下(和类的关系是什么,和类的其他成员之间的关系是什么......)
二,他们被设计出来是解决什么问题的,适用范围,如何使用.....
咱们针对问题,用最少的文字,帮助大家解决了这些问题之后,再多勤加练习。就彻底可以融会贯通了。
一,
①###宏观描述###
--类的成员:代码块(Code Block)指的是在面向对象编程语言中,如Java、C++或C#等,定义在一个类内部的一段代码。
--特征:这段代码被大括号 {} 包围,并且可以在类的不同生命周期阶段执行特定的任务。
--代码块的作用:主要用于初始化操作,它允许程序员在构造函数之外定义一些逻辑,这些逻辑会在对象创建时自动执行。
--代码块分为:静态代码块,实例代码块,同步代码块。
②###具体细节和区别###
三个具体代码块,在执行时机、作用域以及用途上有明显的区别。
静态代码块 :
执行时机: 静态代码块是在类加载时执行,且只执行一次。这意味着无论创建多少个该类的实例,静态代码块都只会执行一次。
作用域: 它属于整个类,而不是某个特定的对象。因此,它只能访问静态变量和静态方法,不能直接访问实例变量或实例方法。
用途: 主要用于初始化类级别的资源,比如配置文件读取、数据库连接池的初始化等。
实例代码块 :
执行时机: 每次创建类的新实例时都会执行实例代码块,且在构造函数之前执行。如果一个类有多个构造函数,那么实例代码块会在每个构造函数调用之前执行。
作用域: 它是与对象相关的,可以访问实例变量和实例方法,也可以访问静态成员。
用途: 通常用于初始化实例变量,特别是当你有多个构造函数并且希望这些构造函数共享一些初始化逻辑时。
同步代码块
执行时机: 同步代码块不是基于类加载或对象创建的时间点来决定是否执行,而是根据程序的执行流程和线程调度情况。当多个线程尝试同时进入同一个同步代码块时,只有其中一个线程能够成功进入并执行,其他线程必须等待当前线程退出同步代码块后才能进入。
作用域: 它的作用范围由synchronized关键字后面的括号内指定的对象决定。它可以是一个对象(如this表示当前对象),也可以是一个类(如ClassName.class表示类本身)。同步代码块内的代码在同一时刻只能被一个线程执行,以保证线程安全。
用途: 主要用于多线程编程中,确保对共享资源的安全访问,避免数据竞争条件和不一致状态。
文字概念看一遍还是模棱两可,老样子。小编给大家举栗子!!
静态代码块:图书馆每天早上开门前需要设置当天的开放时间和特别活动(比如讲座或读书会)。这些信息对所有读者都是一样的,并且只需要设置一次,因为它们适用于整个图书馆。(属于整个类,而不是具体某个对象)
实例代码块:每当有新的读者进入图书馆借书,我们需要记录下他们的借阅时间。因为每个读者的借阅时间都是不一样的,所以我们需要为每个新创建的对象(即每位读者)初始化这个时间。
同步代码块:很多读者都想借阅这本书。为了确保同一时间只有一个读者能够成功借出这本书,我们可以使用同步代码块来保护这段代码。
怎么样,是不是一下就豁然开朗了。再给大家举栗子(具体代码)!!
一,静态代码块
public class Library {
// 静态变量保存今天的开放时间和特别活动
private static String openingHours;
private static String specialEvent;
// 静态代码块,在类加载时执行,用于设置当天的开放时间和特别活动
static {
System.out.println("Setting up today's library schedule...");
openingHours = "9:00 AM - 9:00 PM";
specialEvent = "Book Reading at 3:00 PM";
}
// 构造函数
public Library() {
// 构造函数中的代码...
}
}
当Library类第一次被加载到内存中时,静态代码块会运行并设置openingHours和specialEvent。之后,无论创建多少个Library对象(比如不同的分馆),这些值都不会再次改变,除非手动更新。
二,实例代码块
public class Reader {
// 实例变量保存借阅时间
private String borrowTime;
// 实例代码块,在每次创建对象时执行,先于构造函数
{
System.out.println("Recording the borrow time for a new reader...");
borrowTime = new java.util.Date().toString();
}
// 构造函数
public Reader(String name) {
System.out.println(name + " has entered the library.");
// 构造函数中的其他代码...
}
}
每当创建一个新的Reader对象时,实例代码块会自动执行,为该读者设置当前的时间。这发生在任何构造函数调用之前,所以对于每个新读者,都会有一个独立的借阅时间记录。
三,同步代码块
public class BookManager {
// 共享资源:书籍是否已被借出
private boolean isBorrowed = false;
// 用于同步的锁对象
private final Object lock = new Object();
// 借书的方法
public void borrowBook(String bookTitle, String readerName) {
// 同步代码块,确保同一时间只有一个线程能执行此段代码
synchronized (lock) {
if (!isBorrowed) {
System.out.println(readerName + " successfully borrowed " + bookTitle);
isBorrowed = true;
} else {
System.out.println(bookTitle + " is already borrowed. Sorry, " + readerName);
}
}
}
// 还书的方法
public void returnBook(String bookTitle) {
synchronized (lock) {
isBorrowed = false;
System.out.println(bookTitle + " has been returned.");
}
}
}
borrowBook方法内的同步代码块保证了即使多个读者(代表不同的线程)试图同时借阅同一本书,也只会有一个读者能够成功借出这本书,从而避免了并发问题。同样地,returnBook方法也使用了同步代码块来确保还书操作的安全性。
ok了,小编的分享就到这里。大家按照开头的提出的问题,在文章中一个一个解决掉,多练习多体会。