线程和进程
java默认有两个线程 main 和GC
一个进程包含一个或者多个线程
java真的可以开启线程吗? 开不了
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 */
}
}
}
//是由本地方法区开启线程,java无法直接操作硬件
private native void start0();
并发 和并行
并发(多线程操作同一个资源)快速交替
并行(多个人一起行走)cpu 多核的情况下 可以使用线程池
并发本质:充分利用cpu资源
线程的状态
线程新生
可运行
阻塞
等待 死死等待
超时等待
终止
wait和sleep的区别
-
来自不同的类(wait =》object) sleep=》Thread
-
关于锁的释放
-
使用的范围是不同的,
wait 必须在同步代码块中使用
sleep 可以在任何地方使用
-
是否需要捕获异常 都要捕获异常
Lock锁
Synchronized :
public ReentrantLock() {
sync = new NonfairSync();
}
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
公平锁:先来后到
非公平锁:可以插队(这是默认方式)
Synchronized 和 lock 的区别
1.Synchronized 是一个内置关键字 Lock是一个类
2.Synchronized无法获取说的状态,Lock可以判断是否获取到了锁
3.Synchronized是全自动的 自动释放锁 Lock必须要手动释放 如果不释放,会死锁
4.Synchronized(线程1 获得锁) 线程2 就一直等待 。Lock就不一定会等待下去。
5.Synchronized可重入锁,不可以中断的,非公平的 。Lock可重入锁,可以判断锁,非公平的(可以自己设置)
6.Synchronized 适合锁少量的同步问题,Lock 适合锁大量问题
锁是什么,判断锁的是谁
4.生产者消费者模式
Synchronized 版本
package com.demo01;
import java.util.Date;
/*
线程之间的通信问题 ,生产者消费者问题
线程交替执行
*/
//判断等待 ,业务 ,通知
public class A {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"a").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"b").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"c").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"d").start();
}
}
class Data{//数字 资源类
private int number= 0;
//+1
public synchronized void increment() throws InterruptedException {
while (number != 0){
//等待
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName()+"=>"+number);
//通知其他线程 +1完毕
this.notifyAll();
}
//-1
public synchronized void decrement() throws InterruptedException {
while (number == 0){
//等待
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"=>"+number);
//通知其他线程 -1完毕
this.notifyAll();
}
}
JUC版的 生产者消费者模式
通过Lock找到Condition
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}