方法一、互斥锁+条件变量
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Task{
private int count=1;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void print(int id){
while(true){
lock.lock();
try {
while (count % 3 != id) {
condition.await();
}
if (count > 100) break;
System.out.println(Thread.currentThread().getName() + ": " + count);
count++;
condition.signalAll();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}
public class Main {
public static void main(String[] args) {
Task task = new Task();
Thread thread1 = new Thread(()->{task.print(0);}, "thread 1");
Thread thread2 = new Thread(()->{task.print(1);}, "thread 2");
Thread thread3 = new Thread(()->{task.print(2);}, "thread 3");
thread1.start();
thread2.start();
thread3.start();
}
}
方法二、利用synchronized关键字
Java的每个对象都有一个内部锁,如果一个方法声明时有synchronized关键字,那么对象的锁将保护整个方法。
class Task {
private int count = 1;
public synchronized void print(int id) {
while (true) {
try {
while (count % 3 != id) {
wait();
}
if (count > 100) break;
System.out.println(Thread.currentThread().getName() + ": " + count);
count++;
notifyAll();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Main {
public static void main(String[] args) {
Task task = new Task();
Thread thread1 = new Thread(()->{task.print(0);}, "thread 1");
Thread thread2 = new Thread(()->{task.print(1);}, "thread 2");
Thread thread3 = new Thread(()->{task.print(2);}, "thread 3");
thread1.start();
thread2.start();
thread3.start();
}
}
方法三、同步块语法
java的同步块语法可以获取一个对象的锁使用。
class Task {
private int count = 1;
private static final Object LOCK = new Object();
public void print(int id) {
while (true) {
synchronized (LOCK){
try {
while (count % 3 != id) {
LOCK.wait();
}
if (count > 100) break;
System.out.println(Thread.currentThread().getName() + ": " + count);
count++;
LOCK.notifyAll();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class Main {
public static void main(String[] args) {
Task task = new Task();
Thread thread1 = new Thread(()->{task.print(0);}, "thread 1");
Thread thread2 = new Thread(()->{task.print(1);}, "thread 2");
Thread thread3 = new Thread(()->{task.print(2);}, "thread 3");
thread1.start();
thread2.start();
thread3.start();
}
}