引言:
1.Synchronized:配合wait()、notifyAll();
2.Lock:配合await()、signalAll();
(1)用Synchronized来实现多个线程(四个)对共享资源ticket进行加、减操作;
始终在0 , 1数值两个之间进行切换。
package com.tencent.JUC;
public class Lock {
public static void main(String[] args) throws Exception {
Ticket t = new Ticket();
//四个线程
new Thread( ()->{
for(int i=0;i<10;i++) {
try {
t.incre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} , "A").start();
new Thread( ()->{
for(int i=0;i<10;i++) {
try {
t.decre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} , "B").start();
new Thread( ()->{
for(int i=0;i<10;i++) {
try {
t.incre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} , "C").start();
new Thread( ()->{
for(int i=0;i<10;i++) {
try {
t.decre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} , "D").start();
}
}
class Ticket {
private static int number = 0;
public synchronized void incre() throws InterruptedException {
while(number != 0) { //循环:解决虚拟唤醒的问题
this.wait();
}
System.out.println(Thread.currentThread().getName() + "线程:" + number + "准备+1");
number++;
this.notifyAll(); //唤醒除自己之外的其它几个等待线程
}
public synchronized void decre() throws InterruptedException {
while(number == 0) {
this.wait();
}
System.out.println(Thread.currentThread().getName() + "线程:" + number + "准备-1");
number--;
this.notifyAll();
}
}
(2)同上,改为用Lock锁来实现生产者、消费者问题:
package com.tencent.JUC;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
public static void main(String[] args) throws Exception {
Ticket2 t = new Ticket2();
//四个线程
new Thread( ()->{
for(int i=0;i<10;i++) {
try {
t.incre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} , "A").start();
new Thread( ()->{
for(int i=0;i<10;i++) {
try {
t.decre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} , "B").start();
new Thread( ()->{
for(int i=0;i<10;i++) {
try {
t.incre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} , "C").start();
new Thread( ()->{
for(int i=0;i<10;i++) {
try {
t.decre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} , "D").start();
}
}
class Ticket {
private static int number = 0;
public synchronized void incre() throws InterruptedException {
while(number != 0) { //循环:解决虚拟唤醒的问题
this.wait();
}
System.out.println(Thread.currentThread().getName() + "线程:" + number + "准备+1");
number++;
this.notifyAll(); //唤醒除自己之外的其它几个等待线程
}
public synchronized void decre() throws InterruptedException {
while(number == 0) {
this.wait();
}
System.out.println(Thread.currentThread().getName() + "线程:" + number + "准备-1");
number--;
this.notifyAll();
}
}
class Ticket2 {
private static int number = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition(); //锁的监视器
public void incre() throws InterruptedException {
try {
lock.lock();
//业务代码
while(number != 0) {
condition.await();
}
System.out.println(Thread.currentThread().getName() + "线程:" + number + "准备+1");
number++;
condition.signalAll();
} catch (Exception e ) {
System.out.println(e.getMessage());
} finally {
lock.unlock();
}
}
public void decre() throws InterruptedException {
try {
lock.lock();
//业务代码
while(number == 0) {
condition.await();
}
System.out.println(Thread.currentThread().getName() + "线程:" + number + "准备-1");
number--;
condition.signalAll();
} catch (Exception e ) {
System.out.println(e.getMessage());
} finally {
lock.unlock();
}
}
}
(3)测试:
"C:\Program Files\Java\jdk1.8.0_101\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=59384:D:\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_101\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_101\jre\lib\rt.jar;F:\test-0517-tencent\out\production\test-0517-tencent;F:\test-0517-tencent\src\lib\commons-io-1.4.jar" com.tencent.JUC.LockTest
A线程:0准备+1
B线程:1准备-1
C线程:0准备+1
B线程:1准备-1
A线程:0准备+1
B线程:1准备-1
A线程:0准备+1
B线程:1准备-1
A线程:0准备+1
B线程:1准备-1
A线程:0准备+1
B线程:1准备-1
A线程:0准备+1
B线程:1准备-1
A线程:0准备+1
B线程:1准备-1
A线程:0准备+1
B线程:1准备-1
A线程:0准备+1
B线程:1准备-1
A线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
C线程:0准备+1
D线程:1准备-1
Process finished with exit code 0