用Synchronized和Lock实现交替打印奇偶数。
Synchronized
private static void testSynchronized() {
// 实现 synchronized 多线程交替打印奇数偶数
Object obj = new Object();
Thread thread1 = new Thread(() -> {
for (int i = 0; i <= 100; i++) {
synchronized (obj){
if(i%2==1) System.out.println(Thread.currentThread().getName() + ": " +i);
obj.notifyAll();
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"奇数");
Thread thread2 = new Thread(() -> {
for (int i = 0; i <= 100; i++) {
synchronized (obj){
if(i%2==0) System.out.println(Thread.currentThread().getName() + ": " +i);
obj.notifyAll();
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"偶数");
thread1.start();
thread2.start();
}
lock
public class demo2 {
static volatile boolean flag = false;
private static int count = 0;
private static int timewait = 10;
public static void main(String[] args) {
testLock();
// 实现 lock 多线程交替打印奇数偶数
}
private static void testLock() {
ReentrantLock lock = new ReentrantLock();
Thread thread1 = new Thread(() -> {
while(count <= 100) {
if(!flag) {
lock.lock();
try{
if(count%2==1) System.out.println(Thread.currentThread().getName() + ": " +count++);
flag = true;
}finally {
lock.unlock();
}
}else {
// 防止线程空转
try {
Thread.sleep(timewait);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"奇数");
Thread thread2 = new Thread(() -> {
while(count <= 100) {
if(flag) {
lock.lock();
try{
if(count%2==0) System.out.println(Thread.currentThread().getName() + ": " +count++);
flag = false;
}finally {
lock.unlock();
}
}else {
// 防止线程空转
try {
Thread.sleep(timewait);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"偶数");
thread1.start();
thread2.start();
System.out.println();
}
}
为什么会有lock
一.synchronized的缺陷
synchronized是java中的一个关键字,也就是说是Java语言内置的特性。那么为什么会出现Lock呢?
在上面一篇文章中,我们了解到如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
2)线程执行发生异常,此时JVM会让线程自动释放锁。
那么如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,试想一下,这多么影响程序执行效率。
因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过Lock就可以办到。
再举个例子:当有多个线程读写文件时,读操作和写操作会发生冲突现象,写操作和写操作会发生冲突现象,但是读操作和读操作不会发生冲突现象。
但是采用synchronized关键字来实现同步的话,就会导致一个问题:
如果多个线程都只是进行读操作,所以当一个线程在进行读操作时,其他线程只能等待无法进行读操作。
因此就需要一种机制来使得多个线程都只是进行读操作时,线程之间不会发生冲突,通过Lock就可以办到。
另外,通过Lock可以知道线程有没有成功获取到锁。这个是synchronized无法办到的。
相同点 不同点
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92872.html