共计 1997 个字符,预计需要花费 5 分钟才能阅读完成。
作者:折纸
集体博客:https://www.zhezhi.press
记录菜鸡的成长之旅!
LockSupport
原理
贴一个之前的笔记,字迹比拟潦草 zz 有空的时候这里会补上阐明
实现 1
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
class Main{
static Thread a = null, b=null;
public static void main(String[] args){a = new Thread(new Runnable() {
@Override
public void run() {for(int i = 1;i<=99;i+=2){System.out.println(i);
LockSupport.unpark(b);
LockSupport.park();}
}
});
b = new Thread(new Runnable() {
@Override
public void run() {for(int i = 2;i<=100;i+=2){LockSupport.park();
System.out.println(i);
LockSupport.unpark(a);
}
}
});
a.start();
b.start();}
}
实现 2
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
public class Main {static AtomicInteger num = new AtomicInteger(1);
public static void main(String[] args) throws InterruptedException {Print p1 = new Print();
Print p2 = new Print();
Thread t1 = new Thread(p1); //t1 对应 p1 工作 但 p1 工作的线程挂在 t2 上不便 t1 唤醒它
Thread t2 = new Thread(p2);
t1.setName("thread-cc-1");
t2.setName("thread-cc-2");
p1.setT(t2);// 给 p1 的 Thread 设置为 t2 不便 t1 唤醒它
p2.setT(t1);
t1.start();
t2.start();
// 唤醒线程 t1 打印奇数,线程 1 打印奇数,线程 2 打印偶数
LockSupport.unpark(t1);
}
static class Print implements Runnable {
private volatile Thread t;
@Override
public void run() {while (true) {
// 进入之后立刻阻塞
LockSupport.park();
if (num.get() > 100) {LockSupport.unpark(t);
return;
}
System.out.println(Thread.currentThread().getName() + ":" + num.getAndIncrement());
// 这里的 t 实际上是与 currentThread 不同的另一个线程
// 因而实现了 奇数唤醒偶数线程,偶数唤醒奇数线程
LockSupport.unpark(t);
}
}
public void setT(Thread t) {this.t = t;}
}
}
点评:可拓展性实现 2 绝对较差一些(实现 3 个线程交替打印 etc)
Synchronized + wait/notify 实现
public class Main{public static void main(String[] args){MyPrint print = new MyPrint();
Thread thread1 = new Thread(print,"A");
Thread thread2 = new Thread(print,"B");
thread1.start();
thread2.start();}
}
class MyPrint implements Runnable{
int i = 1;
@Override
public void run() {while (true){synchronized (this){this.notify();// 在这里唤醒的目标是为保障拿到锁的线程只有一个
// 不会立刻开释锁 退出代码块才会开释锁
if (i <= 100){System.out.println(Thread.currentThread().getName()+" "+i++);
}else {return;}
try {this.wait();// 打印过数据的线程期待 必须等到没打印过数字的拿到锁了能力唤醒
} catch (InterruptedException e) {e.printStackTrace();
}
}
}
}
}
正文完