Multi-threading and thread-safe pool

1, thread-safe and non-thread-safe:

Security thread : multi-threaded access, the use of the locking mechanism when there is a thread class operation, other objects can not carry out such operations until the thread to complete another thread to use for such operation, the data does not appear inconsistent or data pollution;

Thread safe : just do not provide data access protection, any thread access at all times to operate, resulting in multiple threads can operate simultaneously to the same object, data corruption and data inconsistencies occur;

For example: We go to the bank to withdraw money, you have a passbook, your wife has a bank card to withdraw money at the same time in different places, there are 100 dollars now account:

Thread safe:
two people can simultaneously operating account, the operating account you get 10 yuan, 90 left;
your wife on account is 100 yuan time to get account operation, but also took $ 10, the last account
households left 90 yuan , your wife operate slowly, and finally left out of account 90 yuan;
thread-safe:
your operation accounts 100 yuan, 100 yuan when the wife is the operating system to process your request random, will account
households was locked, the request can not be wife operation, 90 into account, when acquiring money accounts daughter operand 90, it took $ 10, we only have 80 cells on account;

2、synchronized

Analog two accounts to withdraw money at the same time:

public class Account {
    //账号
	private String accountNo;
	
	//账户余额
	private double balance;
	//construnct function
	public Account(String accountNo, double balance) {
		super();
		this.accountNo = accountNo;
		this.balance = balance;
	}

	//---------setter和getter的方法------
	public String getAccountNo() {
		return accountNo;
	}

	

	public void setAccountNo(String accountNo) {
		this.accountNo = accountNo;
	}

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}
	//---------setter和getter的方法------
}

public class DrawThread extends Thread {

	 private Account account;
	 
	 private double drawAmount;

	public DrawThread(Account account, double drawAmount) {
		super();
		this.account = account;
		this.drawAmount = drawAmount;
	}
	
	@Override
	public void run() {
		/*if there are many threads operate this account ,these threads
		should share this account's resource ,we use synchronized to lock
		the account resorce only one thread can operate this account,when
		it finishes operation ,it should quit and release this account 
		*/
		synchronized (account) {
			if(account.getBalance()>drawAmount) {
		    	   System.out.println("you have draw "+drawAmount+" money!");
		    	   try {
					Thread.sleep(1);
				} catch (Exception e) {
					e.printStackTrace();
				}
		    	   //modify balance
		    	   account.setBalance(account.getBalance()-drawAmount);
		    	   System.out.println("now you account still has :"+account.getBalance());
		       }else {
		    	   System.out.println("this account has no enough money!");
		       }	
		}
	}
}
public class DrawTest {

	public static void main(String[] args) {
		Account account=new Account("123456",1000);
		new DrawThread(account, 800).start();
		new DrawThread(account, 800).start();
		
	}
}
you have draw 800.0 money!
now you account still has :200.0
this account has no enough money!

3、Lock

public class AccountLock {
	//定义锁对象
	private final ReentrantLock lock=new ReentrantLock();
	
    //账号
	private String accountNo;
	
	//账户余额
	private double balance;
	//construnct function
	public AccountLock(String accountNo, double balance) {
		super();
		this.accountNo = accountNo;
		this.balance = balance;
	}

	//---------setter和getter的方法------
	public String getAccountNo() {
		return accountNo;
	}

	

	public void setAccountNo(String accountNo) {
		this.accountNo = accountNo;
	}

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}
	//---------setter和getter的方法------
	
	public void draw(double drawAmount) {
		 lock.lock();
		 System.out.println("add lock to this account and other threads cannot modify this account!");
		 try {
			 if(balance>drawAmount) {
		    	   System.out.println("you have draw "+drawAmount+" money!");
		    	   try {
					Thread.sleep(1);
				} catch (Exception e) {
					e.printStackTrace();
				}
		    	   //modify balance
		    	  setBalance(balance-drawAmount);
		    	   System.out.println("now you account still has :"+balance);
		       }else {
		    	   System.out.println("this account has no enough money!");
		       }
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			lock.unlock();
			System.out.println("unlock this account!");
		}
	}
	
}

4, comparison:
1, Synchronized keyword, and Lock is a class;
2, Synchronized in finished or is abnormal will release the lock, Lock will not take the initiative to release the lock, unlock only call methods in order to finally release lock;
3, Synchronized can not determine whether to acquire a lock, lock can call can determine whether to acquire a lock;
4, Synchronized if there are two threads
thread 1, thread 2 thread 1 then acquire a lock thread 2 waits until the lock
lock If the thread 2 try to get a lock, if not, they would give up
synchronization 5, lock locks suitable for mass synchronization code, synchronized lock for a small amount of code synchronization issues.

5, the thread pool

public class ThreadPoolTest {

	public static void main(String[] args) {
		ExecutorService pool = Executors.newFixedThreadPool(6);
		Runnable target=()->{
			for(int i=0;i<10;i++) {
				System.out.println(Thread.currentThread().getName()+" 的i的值是:"+i);
			}
		};
		pool.submit(target);
		pool.submit(target);
		pool.shutdown();
	}
}
使用步骤:
1、调用Executors的静态工厂方法创建一个ExecutorService 对象,该对象表示一个线程池;
2、创建一个Runnable或者Callable实例,作为线程的执行任务;
3、使用ExecutorService 的submit的提交方法提交Runnable或者Callable实例;
4、使用shutdown()关闭线程池,使用完毕后;

What are the thread pool:
newFixedThreadPool
newCachedThreadPool
newSingleThreadPool
newScheduledThreadPool
newSingleThreadScheduledExecutor

6, ThreadLocal and Collections thread safe method of packaging

Collections

public class CollectionsTest {
    public static void main(String[] args) {
    	
		List list =Arrays.asList("E","F","G");
		List synchronizedList = Collections.synchronizedList(list);
		Collection collection = Collections.synchronizedCollection(list);
		Map map =new HashMap();
		map.put("1", "111");
		map.put("2", "222");
		Map synchronizedMap = Collections.synchronizedMap(map);
		Set set=new HashSet();
		set.add("333");
		Set synchronizedSet = Collections.synchronizedSet(set);
	}
	
}
 包装线程不安全Collcetions提供了多个方法:
     synchronizedCollection()
     synchronizedList
     synchronizedSet
     synchronizedMap

ThreadLocal to use:
ThreadLocal means that if there are multiple threads each thread will have a copy of the thread variable, and the thread can modify variables in this thread


public class ThreadLocalTest {

	private ThreadLocal<Integer> codeNum=new ThreadLocal<Integer>() {
		//给每个线程初始化一个值0
		  protected Integer initialValue() {
			  return 0;
		  };
	};
	
	public void creaseNum() {
		codeNum.set(codeNum.get()+1);
	}
	
	public Integer getNum() {
		creaseNum();
		return codeNum.get();
	}
	
	public static void main(String[] args) {
		ThreadLocalTest test =new ThreadLocalTest();
		test.new TestThread(test).start();
		test.new TestThread(test).start();
		
	}
	
	
	class TestThread extends Thread{
		private  ThreadLocalTest test;
		
		public TestThread(ThreadLocalTest test) {
			this.test = test;
		}

		@Override
		public void run() {
			for(int i=0;i<3;i++) {
				System.out.println(Thread.currentThread().getName()+" ----->"+"now num is "+test.getNum());	
			}
		}
	}
}
我们发现每个线程都共享同一个codeNum实例,但它们并没有发生相互干扰的情况,
而是各自产生独立的codeNum,这是因为我们通过ThreadLocal为每一个线程提供了单独的副本。
Published 15 original articles · won praise 7 · views 2853

Guess you like

Origin blog.csdn.net/xiaocaodeshengri/article/details/100879745