목차
1. 누적 횟수
두 개의 스레드를 사용하여 count 값을 누적합니다.
각 스레드는 1w번 루프를 돌며 변수 count의 값을 누적하며, count의 기본값은 0입니다. 스레드 안전 문제에 주의하세요.
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
//创建一个锁对象
Object locker = new Object();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
synchronized(locker) {
count++;
}
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
synchronized(locker) {
count++;
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(count);
}
아니면 Join() 메소드를 사용하여 쓰는 순서에 주의하여 쓰레드를 잠그지 않고 안전합니다.
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
count++;
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
count++;
}
});
//注意join的顺序及作用
t1.start();
t1.join();
t2.start();
t2.join();
System.out.println(count);
}
2. 순차 인쇄 |
세 개의 스레드가 있으며 각각 A, B, C만 인쇄할 수 있습니다.
ABC를 순서대로 인쇄해야 하며, 10번 인쇄해야 합니다.
출력 예:
알파벳
알파벳
알파벳
알파벳
알파벳
알파벳
알파벳
알파벳
알파벳
알파벳
public static void main(String[] args) throws InterruptedException {
//创建三个锁对象
Object locker1 = new Object();
Object locker2 = new Object();
Object locker3 = new Object();
//线程一
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (locker1) {
try {
locker1.wait();
System.out.print("A");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (locker2) {
locker2.notify();
}
}
});
//线程二
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (locker2) {
try {
locker2.wait();
System.out.print("B");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (locker3) {
locker3.notify();
}
}
});
//线程三
Thread t3 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (locker3) {
try {
locker3.wait();
System.out.println("C");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (locker1) {
locker1.notify();
}
}
});
//启动线程
t1.start();
t2.start();
t3.start();
//让线程先睡眠1秒 主线程往下执行来唤醒锁locker1
Thread.sleep(1000);
synchronized (locker1) {
locker1.notify();
}
}
3. 교착상태 코드
소위 교착 상태란 스레드 1이 잠금 1을 소유하고 스레드 2가 잠금 2를 소유하는 것입니다. 양측 모두 자신의 잠금을 소유한 채 상대방의 잠금을 얻으려고 시도하며 결국 두 스레드는 무선 대기 상태에 들어가게 됩니다. 이것이 교착 상태입니다. .
public static void main(String[] args) {
//创建两个锁对象
Object locker1 = new Object();
Object locker2 = new Object();
//创建两个线程
Thread t1 = new Thread(() -> {
synchronized (locker1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
synchronized (locker2) {
System.out.println(Thread.currentThread().getName());
}
}
},"t1");
Thread t2 = new Thread(() -> {
synchronized (locker2) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
synchronized (locker1) {
System.out.println(Thread.currentThread().getName());
}
}
},"t2");
t1.start();
t2.start();
}
4.순차 인쇄 ||
세 개의 스레드가 있으며 스레드 이름은 a, b, c입니다.
각 스레드는 자신의 이름을 인쇄합니다.
동시에 시작하여 c, b, a 순서로 인쇄해야 합니다.
public static void main(String[] args) throws InterruptedException {
//创建三个锁对象
Object locker1 = new Object();
Object locker2 = new Object();
Object locker3 = new Object();
//线程一
Thread c = new Thread(() -> {
System.out.print(Thread.currentThread().getName()+" ");
},"c"); //c写在这里 线程名
//线程二
Thread b = new Thread(() -> {
try {
//阻塞等待线程c执行完
c.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(Thread.currentThread().getName()+" ");
},"b"); //b写在这里 线程名
//线程三
Thread a = new Thread(() -> {
try {
//阻塞等待线程b执行完
b.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(Thread.currentThread().getName()+" ");
},"a"); //a写在这里 线程名
//启动线程
a.start();
b.start();
c.start();
}