33-Thread synchronization and deadlock

Thread synchronization and deadlock

  In multi-threaded processing, Runnable can be used to describe the resources operated by multiple threads, and Thread describes each thread object, so when multiple threads access the same resource, if the processing is not done properly, data error operations will occur.

Synchronization issues lead to

Write a simple ticket selling program and create several thread objects to realize the processing operation of selling tickets.

class MyThreadTic implements Runnable{
    
    
	private int ticket = 10; 	//总票数
	@Override
	public void run() {
    
    
		// TODO Auto-generated method stub
		while (true) {
    
    
			if(this.ticket > 0) {
    
    
				System.out.println(Thread.currentThread().getName() + "买票,ticket="+ this.ticket--);
			} else {
    
    
				System.out.println("票已卖完!");
				break;
			}
		}
	}
}
public class TicketDemo {
    
    
	public static void main(String[] args) {
    
    
		MyThreadTic mt = new MyThreadTic();
		new Thread(mt, "票贩子A").start();
		new Thread(mt, "票贩子B").start();
		new Thread(mt, "票贩子C").start();
	}
}

The program at this time will create three thread objects, and these three thread objects will sell 10 tickets. At this time, there is no problem (false appearance) when the program sells tickets, and the problem will be exposed after the delay is added (the number of tickets is negative). At this time, it is necessary to ensure thread data synchronization.
rlvoef.png

Thread synchronization

  The key to solving the synchronization problem is "lock", that is, when a thread performs an operation, other threads wait outside;
r18l4O.png

  To achieve this lock, you can use the synchronized keyword to achieve. Use this keyword to define a synchronization method or a synchronized code block. The code in the synchronized code block allows only one thread to execute.

synchronized(同步对象){
    
    
	同步代码操作;
}

Example: Generally, the current object this can be used for synchronization when processing synchronization objects.

class MyThreadTic implements Runnable{
    
    
	private int ticket = 10; 	//总票数
	@Override
	public void run() {
    
    
		while (true) {
    
    
			synchronized (this) {
    
    		//每一次只允许一个线程进行访问
				if(this.ticket > 0) {
    
    
					try {
    
    
						Thread.sleep(100);
					} catch (InterruptedException e) {
    
    
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + "买票,ticket="+ this.ticket--);
				} else {
    
    
					System.out.println("票已卖完!");
					break;
				}
			}
		}
	}
}
public class TicketDemo {
    
    
	public static void main(String[] args) {
    
    
		MyThreadTic mt = new MyThreadTic();
		new Thread(mt, "票贩子A").start();
		new Thread(mt, "票贩子B").start();
		new Thread(mt, "票贩子C").start();
	}
}

After adding synchronization, the overall performance of the program is reduced, and synchronization will actually cause performance degradation .
Example: UseSynchronization methodTo solve it, just use the synchronized keyword on the method definition.

class MyThreadTic implements Runnable{
    
    
	private int ticket = 10; 	//总票数
	public synchronized boolean sale() {
    
    
		if(this.ticket > 0) {
    
    
			try {
    
    
				Thread.sleep(100);
			} catch (InterruptedException e) {
    
    
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "买票,ticket="+ this.ticket--);
			return true;
		} else {
    
    
			System.out.println("票已卖完!");
			return false;
		}
	}
	@Override
	public void run() {
    
    
		while (this.sale()) {
    
    
			;
		}
	}
}
public class TicketDemo {
    
    
	public static void main(String[] args) {
    
    
		MyThreadTic mt = new MyThreadTic();
		new Thread(mt, "票贩子A").start();
		new Thread(mt, "票贩子B").start();
		new Thread(mt, "票贩子C").start();
	}
}

  When studying the system class library in the future, I found that the synchronization process used on many classes in the system adopts the synchronization method.

Thread deadlock

  Deadlock is a problem that may arise in the process of multi-thread synchronization. The so-called deadlock refers to a state where several threads are waiting for each other.
Observe the deadlock

class Person{
    
    
	public synchronized void say(Dog dog) {
    
    
		System.out.println("out!");
		dog.get();
	}
	public synchronized void get() {
    
    
		System.out.println("Nice!");
	}
}
class Dog{
    
    
	public synchronized void say(Person per) {
    
    
		System.out.println("wangwang!");
		per.get();
	}
	public synchronized void get() {
    
    
		System.out.println("shit!");
	}
}
public class DeadLock implements Runnable {
    
    
	private Person per = new Person();
	private Dog dog = new Dog();
	@Override
	public void run() {
    
    
		per.say(dog);
	}
	public DeadLock() {
    
    
		new Thread(this).start();
		dog.say(per);
	}
	public static void main(String[] args) {
    
    
		new DeadLock();
	}
}

The main cause of deadlock is waiting for each other, waiting for each other to give up resources. Deadlock is actually an indeterminate state in development. Sometimes, improper code processing will cause deadlock to occur irregularly, which is a debugging problem in normal development.
  When several threads access the same resource, they must be synchronized, and too much synchronization will cause deadlock.

Guess you like

Origin blog.csdn.net/MARVEL_3000/article/details/111467474