什么是JUC
JUC是Java一个并发工具包,即java.unit.concurrent
并发和并行
说起并发就不可避免的说下并行,有些人可能还不清楚并发和并行
在我看来
并发:多线程操作同一个资源
并行:多个线程一起跑
在CPU的角度看
并发:CPU一核,模拟出多条线程,快速交替
并行:CPU多核,多个线程可以同时执行;线程池
并发编程的本质
充分利用CPU的资源
线程和进程的区别
进程:一个程序,程序的集合,一个进程往往包含多个线程(至少包含一个)
线程:比如我们开启一个Typora,我们在打字,他自动保存(由一个线程负责)
对java而言开启线程的方式:Thread,Runable,Callable
但是Java真的可以开启线程吗
不可以,在我们平时开启线程使用的是start方法,我们可以看看他的源代码
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
// 只能通过本地方法去调,调用了底层的C++,java无法操作硬件,因为JVM
private native void start0();
在start方法中,我们可以看到他调用了start0方法,这个方法是一个native方法,也就是说这个方法是一个本地方法,由JVM去处理的,也就是说他是由C++来处理的
sleep和wait的区别
.1.来自不同的类
sleep方法来着Thread类
wait方法来着Object类
但是在JUC里面有一个枚举类完全可以代替sleep,具体我们在下面再讲
2.关于锁的释放
wait会释放锁
sleep不会释放锁
3.使用的范围不同
wait必须存在于同步代码块中,
sleep 可以在任何地方
TimeUnit
TimeUnit在官方文档是这么解释的:表示给定的粒度单位的持续时间,并且提供了跨单元转换的实用方法,并且在这些单元中执行定时和延迟操作。
也就是说,这个枚举解决了sleep毫秒的换算问题,能一眼就能看出这个sleep了多久,
举个例子
TimeUnit.SECONDS.sleep(5);//睡眠5秒
Thread.sleep(5000);//睡眠五秒
这样你可能看不出啥,但是这个数字变大了,TimeUnit可以将单位转换,而sleep就需要计算毫秒数
Lock 锁
关于锁的问题有很多,在平时我们使用锁,一般是使用synchronized来进行锁的处理,在JUC里面,有专门的锁,而且实用性更高,那就是Lock
Lock是一个接口,但是我们可以看看他的方法
这是jdk1.8的api里面的描述,我们可以看到他的方法就是关于锁的处理,加锁lock() 解锁unlock()
他与synchronized有什么不同呢?
我们用代码来看看他们在使用有什么区别
传统的synchronized
public class Demo01 {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(()->{
phone.call();
},"A").start();
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone{
public synchronized void call(){
System.out.println(Thread.currentThread().getName()+"call");
sms();
}
public synchronized void sms(){
System.out.println(Thread.currentThread().getName()+"sms");
}
}
Lock版
public class Demo02 {
public static void main(String[] args) {
Phone2 phone = new Phone2();
new Thread(()->{
phone.call();
},"A").start();
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone2{
Lock lock = new ReentrantLock();
public void call(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+"call");
sms();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void sms(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+"sms");
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
我们可以发现,这样实现和synchronized没有任何的区别,唯一的区别可能就是synchronized作用于方法代表synchronized(this) 而lock锁他是以一个对象的形式来实现的
个人理解
望指教