线程同步锁和异步锁的几种方式

同步锁:当在一个java虚拟机多个线程操作一个变量的时候就会出现线程安全问题,这个时候就会用到同步锁。

同步锁的解决方式:

先看下一个线程异常的售票

public class ThreadSafe {
	
	public static void main(String[] args) {
		MyThread t1 = new MyThread("窗口一");
		MyThread t2 = new MyThread("窗口一");
		
		t1.start();
		t2.start();
		
		try {
			t1.join();
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	
	static class MyThread extends Thread{
		
		private static int count = 10;
		
		public MyThread(String name) {
			super(name);
		}
		
		@Override
		public void run() {
			while(count > 0) {
				System.out.println(Thread.currentThread().getName()+"售出:"+(count--) +" 票");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

synchronized 解决的三种方式:1)使用synchronized 静态代码块    2)synchronized 同步方法  3)synchronized 同步类  

public class ThreadSafe {
	
	public static Object obj = new Object();
	
	public static void main(String[] args) {
		MyThread t1 = new MyThread("窗口一");
		MyThread t2 = new MyThread("窗口一");
		
		t1.start();
		t2.start();
		
		try {
			t1.join();
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	static class MyThread extends Thread{
		
		private static int count = 10;
		
		public MyThread(String name) {
			super(name);
		}
		
		@Override
		public void run() {
			while(count > 0) {
				//静态代码块锁,定义同一个对象
				synchronized (obj) {
					System.out.println(Thread.currentThread().getName()+"售出:"+(count--) +" 票");
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
//使用synchronized 定义的方法锁
public class ThreadSafe1 {
	
	public static Object obj = new Object();
	
	public static void main(String[] args) {
		//这个地方必须是对同一个对象进行操作
		MyThread myThread = new MyThread();
		Thread t1 = new Thread(myThread, "窗口一");
		Thread t2 = new Thread(myThread, "窗口二");
		
		t1.start();
		t2.start();
		
		try {
			t1.join();
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	static class MyThread implements Runnable{
		
		private static int count = 10;
		
		//方法锁
		public synchronized void increse() {
			System.out.println(Thread.currentThread().getName()+"售出:"+(count--) +" 票");
		}
		
		@Override
		public void run() {
			while(count > 0) {
				increse();
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
//使用类锁
public class ThreadSafe2 {
	
	public static void main(String[] args) {
		MyThread t1 = new MyThread("窗口一");
		MyThread t2 = new MyThread("窗口一");
		
		t1.start();
		t2.start();
		
		try {
			t1.join();
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	static class MyThread extends Thread{
		
		private static int count = 10;
		
		public MyThread(String name) {
			super(name);
		}
		
		public static synchronized void increase() {
			System.out.println(Thread.currentThread().getName()+"售出:"+(count--) +" 票");
		}
		
		@Override
		public void run() {
			while(count > 0) {
				//静态代码块锁,定义同一个对象
				increase();
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

2.使用lock的解决方式

//使用类锁
public class ThreadSafe3 {
	
	public static Lock lock = new ReentrantLock();
	
	public static void main(String[] args) {
		MyThread t1 = new MyThread("窗口一");
		MyThread t2 = new MyThread("窗口二");
		
		t1.start();
		t2.start();
		
		try {
			t1.join();
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	static class MyThread extends Thread{
		
		private static int count = 10;
		
		public MyThread(String name) {
			super(name);
		}
		
		public static void increase() {
			lock.lock();
			try {
				System.out.println(Thread.currentThread().getName()+"售出:"+(count--) +" 票");
			}catch (Exception e) {
				e.printStackTrace();
			}finally {
				lock.unlock();
			}
			
		}
		
		@Override
		public void run() {
			while(count > 0) {
				//静态代码块锁,定义同一个对象
				increase();
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

异步锁:就是多个java 虚拟机或者说是服务器,操作同一个变量是,会出现线程安全问题,使用需要使用异步锁来处理。

1)数据库  乐观锁 悲观锁 唯一标示  不推荐使用,容易出现锁表,出现死锁。

2)Redis 分布式锁 ,就是设置一个flag标识,当一个服务拿到锁以后立即把对应的标识设置为false  用完后释放锁,并把标识修改为true 详见如下:

3)使用dubbo  zookeeper (共享锁,排它锁),这里就根据自己的情况,共享锁还是会出现阻塞的情况,排它锁就是会生成很多临时的节点,谁先获取最小的序号标识谁就先获取到锁。

猜你喜欢

转载自blog.csdn.net/qq_18430613/article/details/82585844
今日推荐