java基础知识点_基础知识整理之Java基础知识点梳理(详细)

注意当catch语句要捕获多种异常类型时,参数(在这里是e)隐式地成为final变量。

方法声明异常throws,抛出异常throw。

try-with-resources子句(Java SE 7以后)

援引官网的介绍吧:

The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

线程

线程是操作系统调度的最小单元,也叫轻量级进程。同一进程可以创建多个线程,而他们都拥有各自的计算器、堆栈和局部变量等属性,并且能够访问共享的内存变量。

线程的5个状态

创建(New):使用new关键字创建一个线程

就绪(Ready):调用start方法,等待CPU调度

运行(Running):执行run方法

阻塞(Blocked):由于一些原因放弃CPU使用权,暂时停止执行

死亡(Dead):run方法执行完毕或者执行时产生异常

几个重要的名词区分

同步和异步

同步方法调用后必须等待方法返回才能执行后续行为;异步方法调用后可以立刻执行后续行为。

并发和并行

并行是真正意义上的多个任务同时执行;并发是支持处理多个任务,不一定要同时,多个任务可能是串行的,但每个任务只能获取CPU很短的占用时间,多个任务在很短的时间内交替执行。

我相信你已经能够得出结论——“并行”概念是“并发”概念的一个子集。也就是说,你可以编写一个拥有多个线程或者进程的并发程序,但如果没有多核处理器来执行这个程序,那么就不能以并行方式来运行代码。因此,凡是在求解单个问题时涉及多个执行流程的编程模式或者执行行为,都属于并发编程的范畴。

阻塞和非阻塞

阻塞是指某一线程访问一公共资源时其他线程必须等待该线程释放资源才可以使用,否则就要挂起线程等待;非阻塞是指线程之间不会发生资源争夺。

原子性

原子性是指一个操作是不可被中断的,即使多个线程是同时执行的。

可见性

可见性是指当某个线程修改了共享变量的值,其他线程能否立刻知晓。

有序性

Java内存模型中的程序天然有序性可以总结为一句话:如果在本线程内观察,所有操作都是有序的;如果在一个线程中观察另一个线程,所有操作都是无序的。前半句是指“线程内表现为串行语义”,后半句是指“指令重排序”现象和“工作内存和主内存同步延迟”现象。

Java中提供了关键字volatile和synchronized关键字来保证线程之间操作的有序性。volatile包含了禁止指令重排序的语义,并保证不同线程对同一变量操作时的可见性;synchronized关键字对同一时刻同一变量只允许一个线程对其进行lock操作。

线程创建

继承Thread类重写run()方法

匿名内部类,即在new Thread()后跟具体的定义体,其中重写了run()方法

实现Runnable接口,重写run()方法

开启线程的run()和start()方法区别

run()方法不能新建一个线程,而是在当前线程中调用run()方法;

start()方法新建一个线程并调用其run()方法。

终止线程不要使用stop()

一般情况下,线程在执行完毕后就会结束,无需手工关闭,但是我们也经常会创建无限循环的后台进程以持续提供某项服务,所以就需要手动关闭这些线程。

在JDK中也有终止线程的API,例如stop()方法,但是极度不推荐这个方法,因为stop()方法得到调用后,会强行把执行到一半的线程终止,可能会引起数据不一致问题。

但是想要终止一个无限循环的线程应该怎么做?

我们推荐的做法是在类中添加一个isStop的布尔值属性,判断isStop为true则跳出循环体,线程执行完毕自动终止,就避免了数据不一致的问题。

wait() 和notify()

这两个方法不是Thread类特有的,而是所有类的父类Object中的。

当一个对象调用了wait方法后,如:objectA.wait(),当前线程就会在这个对象上等待,会释放该对象的锁,直到其他线程调用了objectA.notify()方法为止。

需要注意的是,wait和notify方法都必须获得对象的监视器(锁),在同步代码得到执行后也会释放对象的锁,所以必须被包含在对象的synchronzied语句中。

(注:以上内容援引他人文章,原作者声明:作者:kk_miles链接:https://juejin.im/post/5a30a7466fb9a0450f21ec5c来源:掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。)

小题

public class WaitNotifyDemo {

final static Object object = new Object();

public static class Thread1 extends Thread{

@Override

public void run() {

synchronized (object){

System.out.println(System.currentTimeMillis()+" 线程1开启。。");

try {

object.wait(); //1.先获取object的锁,然后开始等待,并再次释放object的锁。

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(System.currentTimeMillis()+" 线程1结束。。"); //4f. 两秒后,线程2执行结束,线程结束,重新获得了object的锁,此句猜得到执行

}

}

}

public static class Thread2 extends Thread{

@Override

public void run() {

synchronized (object){

System.out.println(System.currentTimeMillis()+" 线程2开启,并执行notify通知线程1 。。");

object.notify(); //2.获取object的锁成功,通知object的其他线程(即线程1),这里还未释放object的锁!

System.out.println(System.currentTimeMillis()+" 线程2执行notify结束。。");

try {

Thread.sleep(2000); //3. 使线程2暂停2秒,即2秒后线程2才能执行结束,才能把object的锁释放。

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(System.currentTimeMillis()+" 线程2结束。。");

}

}

}

public static void main(String[] args) {

Thread thread1 = new Thread1();

Thread thread2 = new Thread2();

thread1.start();

thread2.start();

}

}

以上代码是一个关于wait和notify的示意代码,声明一个静态对象和两个静态内部类表示两个线程,连个线程分别在对象object的同步块中调用wait和notify方法,在线程1中调用了object的wait方法前需要先获取object的锁,然后进入线程等待,并释放锁;然后线程2的notify方法执行前需要获取object的锁,然后通知线程1。但是此时线程1仍然无法执行wait方法后面的代码,原因是线程2Thread.sleep(2000)使得线程2在2秒之后才能退出并且释放object的锁,也即线程1必须等待线程2的object同步代码块执行结束后才能获得锁,去继续执行下面的代码,具体的输出日志如下:

1510300350884 线程1开启。。

1510300350884 线程2开启,并执行notify通知线程1 。。

1510300350884 线程2执行notify结束。。

1510300352884 线程2结束。。 //2秒中之后线程2结束,释放object锁

1510300352885 线程1结束。。 //线程2释放锁之后,线程1获得锁,结束等待状态,继续向下执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值