Multi-threaded concurrent acquisition of order number

Reproduce a high concurrency scenario using a countdown counter (semaphore):
package com.baozun.trade;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OrderTest implements Runnable {


	private Logger log = LoggerFactory.getLogger(OrderTest.class);
	
	private static final int MUN = 10;
	// lock, semaphore (jkd packet countdown counter), event mechanism
	private static CountDownLatch cdl = new CountDownLatch(MUN);
	
	private static Lock lock = new ReentrantLock();
	
	private static int i =0;

	public void createOrder() {
		String orderCode = getOrderCode();
//		lock.lock();
		log.info(Thread.currentThread().getName()+" ========" + orderCode);
	}


	public void run() {
		try {
			// Wait for the other 9 threads to initialize
			cdl.await ();
		} catch(InterruptedException e) {
			e.printStackTrace ();
		}
		createOrder();
	}
	
	public static void main(String[] args) throws InterruptedException{
		// TODO Auto-generated method stub
		for(int i =1; i <= MUN; i++) {
			
			new Thread(new OrderTest()).start();
			cdl.countDown ();
		}
		Thread.currentThread().sleep(3000);
	}

	private String getOrderCode() {

		Date now = new Date();
		SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return sdf.format(now) +":" + ++i;
	}
}

operation result:
2017-12-20 19:53:42.929 [Thread-1] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-1 ========2017-12-20 19:53:42:1
2017-12-20 19:53:42.929 [Thread-7] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-7 ========2017-12-20 19:53:42:3
2017-12-20 19:53:42.929 [Thread-2] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-2 ========2017-12-20 19:53:42:6
2017-12-20 19:53:42.929 [Thread-4] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-4 ========2017-12-20 19:53:42:5
2017-12-20 19:53:42.929 [Thread-3] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-3 ========2017-12-20 19:53:42:8
2017-12-20 19:53:42.929 [Thread-9] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-9 ========2017-12-20 19:53:42:9
2017-12-20 19:53:42.929 [Thread-5] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-5 ========2017-12-20 19:53:42:4
2017-12-20 19:53:42.929 [Thread-6] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-6 ========2017-12-20 19:53:42:2
2017-12-20 19:53:42.929 [Thread-8] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-8 ========2017-12-20 19:53:42:2
2017-12-20 19:53:42.929 [Thread-0] INFO  OrderTest.java:28 com.baozun.trade.OrderTest -Thread-0 ========2017-12-20 19:53:42:7


It is found that the order number 2 is repeated, and there is a thread unsafe

solution
synchronization lock
http://blog.csdn.net/lianqiangjava/article/details/12652201/
http://bbs.csdn.net/topics/390868532
Synchronization code block:
private String getOrderCode() {
		String orderCode = "";
		synchronized (this){  
			Date now = new Date();
			SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			orderCode =  sdf.format(now) +":" + ++i;
		}
		return orderCode;
}or
private synchronized  String getOrderCode() {
		String orderCode = "";
			Date now = new Date();
			SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			orderCode =  sdf.format(now) +":" + ++i;
		return orderCode;


The above will be found to be invalid, the reason is that five new instances are created, and there are five memory addresses that cannot be shared.
private static synchronized  String getOrderCode() {
		String orderCode = "";
		synchronized (this){  
			Date now = new Date();
			SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			orderCode =  sdf.format(now) +":" + ++i;
		}
		return orderCode;
	}

lock lock , more flexible When
an exception occurs, it cannot be unlocked, and a lock needs to be added in finally to avoid deadlock.
Let each thread enter the lock.

public void createOrder() {
		lock.lock();
		try {
			String orderCode = getOrderCode();
			log.info(Thread.currentThread().getName()+" ========" + orderCode);
		} catch (Exception e) {
			e.printStackTrace ();
		} finally {
			lock.unlock();
		}
	}



Distributed lock implementation technology:
write table data, the table has a unique primary key, each thread has a unique build and inserts at the same time, only one thread successfully inserts, and then unlocks (and then finds the data to delete).
1. The
maximum concurrent peak value of mysql is 1000 for distributed locks based on the database. The lock has no expiration
time, which is easy to deadlock. Non-
blocking and
non-reentrant It is easy to deadlock and cannot be rewritten http://blog.csdn.net/fansunion/article/details/52302650 3. Implementing distributed locks based on zookeeper Relatively simple implementation , strong reliability and good performance zk data structure is a tree, like a Unix file The system paths are similar, and each node stores data. Through the client, you can add, delete, and modify zk, and you can register watchers to monitor zk changes. zk node types: persistent node (Persistent) persistent sequential node (Persistent_sequential) temporary node (Ephemeral) temporary sequential node (Ephemeral_sequential) For persistent nodes and temporary nodes, the same zk Below, the names of the nodes are unique.


























Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326285701&siteId=291194637