Java线程同步 线程死锁
解决超卖
package ersatz.thread;
public class T {
public static void main(String[] args) {
Ticket ticket = new Ticket();
new Thread(ticket).start();
new Thread(ticket).start();
new Thread(ticket).start();
}
}
class Ticket implements Runnable {
private int number = 50;
private boolean loop = true;
Object o = new Object();
// 同步方法(static)的锁为当前类
// public synchronized static void m(){} 锁加在Ticket.class
// 静态方法中,实现一个同步代码块
// synchronized (Ticket.class) {
//
// }
public static void m() {
synchronized (Ticket.class) {
System.out.println();
}
}
// public synchronized void m(){}是一个同步方法,锁在this,可在代码块写synchronized,同步代码块,互斥锁还是在this
public /*synchronized*/ void sell() { // 同步方法,在同一时刻,只能有一个线程来执行sell方法
synchronized (/*this*/ o) {
if (number <= 0) {
System.out.println("ticket out of number");
loop = false;
return;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " sell ticket " + "left: " + --number);
}
}
@Override
public void run() {
while (loop) sell();
}
}
以下代码不能解决超卖
package ersatz.thread;
public class T {
public static void main(String[] args) {
Ticket ticket1 = new Ticket();
Ticket ticket2 = new Ticket();
Ticket ticket3 = new Ticket();
ticket1.start();
ticket2.start();
ticket3.start();
}
}
class Ticket extends Thread {
private static int number = 50;
private boolean loop = true;
public void sell() {
synchronized (this) {
if (number <= 0) {
System.out.println("ticket out of number");
loop = false;
return;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " sell ticket: " + number + ", left: " + --number);
}
}
@Override
public void run() {
while (loop) sell();
}
}


Deadlock
package ersatz.thread;
public class T {
public static void main(String[] args) {
Deadlock d1 = new Deadlock(true);
Deadlock d2 = new Deadlock(false);
d1.setName("Thread-A");
d2.setName("Thread-B");
d1.start();
d2.start();
}
}
class Deadlock extends Thread {
protected static final Object o1 = new Object(); // 保证多线程共享同一对象
protected static final Object o2 = new Object();
protected boolean flag;
public Deadlock(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
//1. 如果flag 为 T, 线程A 就会先得到/持有 o1 对象锁, 然后尝试去获取 o2 对象锁
//2. 如果线程A 得不到 o2 对象锁,就会Blocked
//3. 如果flag 为 F, 线程B 就会先得到/持有 o2 对象锁, 然后尝试去获取 o1 对象锁
//4. 如果线程B 得不到 o1 对象锁,就会Blocked
if (flag) {
synchronized (o1) { // 对象互斥锁,下面为同步代码
System.out.println(Thread.currentThread().getName() + " obtain o1 lock");
synchronized (o2) {
System.out.println(Thread.currentThread().getName() + " obtain o2 lock");
}
}
} else {
synchronized (o2) {
System.out.println(Thread.currentThread().getName() + " obtain o2 lock");
synchronized (o1) {
System.out.println(Thread.currentThread().getName() + " obtain o1 lock");
}
}
}
}
}


释放锁:

下列操作不会释放锁


package ersatz.thread;
import java.util.Scanner;
public class T {
public static void main(String[] args) {
A a = new A();
B b = new B(a);
a.setName("Thread-A");
b.setName("Thread-B");
a.start();
b.start();
}
}
class A extends Thread {
private boolean loop = true;
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run() {
while (loop) {
System.out.println((int) (Math.random() * 100 + 1));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " exit");
}
}
class B extends Thread {
private A a = null;
private final Scanner scanner = new Scanner(System.in);
public B(A a) {
this.a = a;
}
@Override
public void run() {
while (true) {
System.out.println("input Q to exit:");
char key = scanner.next().toUpperCase().charAt(0);
if (key == 'Q') {
a.setLoop(false);
System.out.println(Thread.currentThread().getName() + " exit");
break;
}
}
}
}

package ersatz.thread;
public class T {
public static void main(String[] args) {
B b = new B();
Thread t1 = new Thread(b);
t1.setName("Thread-A");
Thread t2 = new Thread(b);
t2.setName("Thread-B");
t1.start();
t2.start();
}
}
class B implements Runnable{
private int balance=10000;
@Override
public void run() {
do {
synchronized (this) {
if (balance < 1000) {
System.out.println("insufficient balance: " + balance+' '+Thread.currentThread().getName()+" exit");
break;
}
System.out.println(Thread.currentThread().getName() + " withdraw 1000, balance: " + (balance -= 1000));
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (true);
}
}

浙公网安备 33010602011771号