static Object obj=new Object();
static Lock lock=new ReentrantLock(); //锁对象
lock.lock();
lock.unlock();
死锁现象
public static void main(String[] args) {
MyThread th1 = new MyThread(true);
MyThread th2 = new MyThread(false);
th1.start();
th2.start();
}
public static final Object objA=new Object();
public static final Object objB = new Object();
public class MyThread extends Thread {
private boolean flag;
public MyThread(boolean b) {
this.flag = b;
}
@Override
public void run() {
if (flag) {
synchronized (ObjectUtils.objA) {
System.out.println("true 进来了,持有objA");
synchronized (ObjectUtils.objB) {
System.out.println("true 进来了,持有objB");
}
}
} else {
synchronized (ObjectUtils.objB) {
System.out.println("false 进来了,持有objB");
synchronized (ObjectUtils.objA) {
System.out.println("false 进来了,持有objA");
}
}
}
}
}
Object 类中的线程等待 和唤醒
void wait ()
在其他线程调用此对象的 notify () 方法或 notifyAll () 方法前,导致当前线程等待。
void wait ( long timeout)
在其他线程调用此对象的 notify () 方法或 notifyAll () 方法,或者超过指定的时间量前,导致当前线程等待。
void notify()
唤醒在此对象监视器上等待的单个线程。
void notifyAll()
唤醒在此对象监视器上等待的所有线程。
wait() sleep(); 共同点是可以让线程,处于阻塞状态
slepp(1000) 必须要传入时间量
wait() 可以传入时间量,也可以不传
sleep() 一旦休眠 不释放锁
wait() 一旦等待就要释放锁
public class GetThread extends Thread{//消费线程:消费了资源,等着,通知生产者去生产
Student student;
public GetThread(Student student) {
this.student=student;
}
@Override
public void run() {
while (true){
synchronized (student){
if(!student.flag){ //消费者:没有资源等待
try {
student.wait(); //等待:wait()方法,一旦等待,就要释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费
System.out.println(student.name + "===" + student.age);
//通知
student.flag=false; //修改标记
student.notify();//
}
}
}
}
public class SetThread extends Thread{
Student student;
int i=0;
public SetThread(Student student) {
this.student=student;
} //生产线程:当我生产出一个资源时,我等着,通知消费者消费
@Override
public void run() {
while (true){
//set
synchronized (student){
if(student.flag){ //有资源
//生产线程,有资源 等待
try {
student.wait(); //一旦等待,就要释放锁。从哪里等待,被唤醒后,就从这里醒来
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (i % 2 == 0) {
student.name = "张三"; //张三
student.age = 23; //set get
} else {
//set
student.name = "李四";
student.age = 24;
}
//说明有资源了:通知消费者去消费
student.flag=true; //修改标记
student.notify(); //一旦通知,两个再次抢占时间片
}
i++;
}
}
}
public class Student { //资源
public String name;
public int age;
public boolean flag=false; //false 代表没有资源,true 代表有资源
}
volatile 可以解决内存可见性的问题 不用加锁、
volatile 变量,用来确保将变量的更新操作通知到其他线程。
可以将 volatile 看做一个轻量级的锁,但是又与
锁有些不同:
对于多线程,不是一种互斥关系
不能保证变量状态的“原子性操作”
原子性:不可再分割性
i++ i–
public class MyTest {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable).start();
while (true){
if (myRunnable.getFlag()) {//true
System.out.println("进来了");
break;
}
}
}
}
class MyRunnable implements Runnable{
//volatile 可以解决内存可见性的问题 不用加锁
volatile boolean flag=false;
public boolean getFlag() {
return flag;
}
@Override
public void run() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag=true; //把flag的值设为true
System.out.println("线程将flag的值设为"+flag);
}
}
CAS算法
public class MyTest {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(myRunnable);
thread.start();
}
}
}
class MyRunnable implements Runnable{
// int i=1;
//Java 提供的原子变量,实现了CAS 算法
AtomicInteger i= new AtomicInteger(1);
public int getI() {
// return //i++; //++ -- 不是原子性的操作,他要经历 读改写
return i.getAndDecrement();
}
@Override
public void run() {
while (true){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+": "+getI());
}
}
}