多线程同步的两大方式 Synchronized 和 lock的使用 及 synchronized对象锁与全局锁。什么时候是对象锁,什么时候是全局锁。

所谓的同步指的并不是所有的线程一起进入到方法中执行,而是按照顺寻一个一个的进来

Synchronized 处理同步问题

使用Synchronized关键字处理有两种模式:同步代码块,同步方法

一、同步代码块:

如果要使用同步代码块必须设置一个要锁定的对象,所以一般可以锁定当前对象。

并且synchronized 同步的代码块,在同一时刻只允许一个线程进入代码块处理

这种方式是在方法中拦截的,也就是说进入到方法中的线程依然会有很多个。

class MyThread implements Runnable{
	private int ticket=10;
	public void run() {
		for(int i=0;i<10;i++) {
			//synchronized   在同一时刻只允许一个线程进入代码块处理
			synchronized (this) {
				try {
					Thread.sleep(1000);
					System.out.println("当前进程名"+Thread.currentThread().getName()+
							"、还剩票数:"+ticket--);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
public class Test2 {
	public static void main(String[] args) {
		MyThread myThread=new MyThread();
		Thread t1=new Thread(myThread,"黄牛A");
		Thread t2=new Thread(myThread,"黄牛B");
		t1.start();
		t2.start();
	}

}

 

 

二、同步方法

进入到方法中的线程只有一个。

class MyThread implements Runnable{
	private int ticket=10;
	public void run() {
		for(int i=0;i<10;i++) {
			this.sale();
		}
	}
        //进入到方法中的线程只有一个
	public synchronized void sale() {
		if(this.ticket>0) {
		try {
			Thread.sleep(100);		
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("当前线程为"+Thread.currentThread().getName()
				+"剩余票数:"+this.ticket--);		
	  }
      }
}
public class Test2 {
	public static void main(String[] args) {
		MyThread myThread=new MyThread();
		Thread t1=new Thread(myThread,"黄牛A");
		Thread t2=new Thread(myThread,"黄牛B");
		t1.start();
		t2.start();
	}
}

对象锁:

锁住同一个对象

class Sync{
	public void test() {
		synchronized(this) {
			System.out.println("test方法开始,当前线程为:"+Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("test方法结束,当前线程为:"+Thread.currentThread().getName());
		}
	}
}
class MyThread implements Runnable{
	private Sync sync;

	public MyThread(Sync sync) {
		super();
		this.sync = sync;
	}
	public void run() {
		this.sync.test();
	}
}
public class Test2 {
	public static void main(String[] args) {
		Sync sync=new Sync();
		MyThread myThread=new MyThread(sync);
		for(int i=0;i<3;i++) {
			Thread thread=new Thread(myThread);
			thread.start();
		}
	}
}

全局锁:

使用synchronized锁住这个类对应的Class对象

下面代码使用synchronized(Sync.class)实现了全局锁的效果,因此要想锁住的是代码段,锁住多个对象的同一方法,使用这种全局锁,锁住的是类而不是this

static synchronized 方法,staic方法可以直接类名加方法名调用,方法中无法使用this,所以它锁的不是this,而是类的class对象,,所以statci synchronized 方法也相当于全局锁,相当于锁住了代码段。

class Sync{
	public void test() {
		synchronized(Sync.class) {
			System.out.println("test方法开始,当前线程为:"+Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("test方法结束,当前线程为:"+Thread.currentThread().getName());
		}
	}
}

class MyThread implements Runnable{
	public void run() {
			Sync sync=new Sync();
			sync.test();
	}
}

public class Test2 {
	public static void main(String[] args) {
		for(int i=0;i<3;i++) {
		MyThread myThread=new MyThread();
		Thread thread=new Thread(myThread);
		thread.start();
		}
	}
}

JDK1.5提供的Lock锁

class MyThread implements Runnable{
	private int ticket=10;
	private Lock ticketLock=new ReentrantLock();
	public void run() {
		for(int i=0;i<10;i++) {
			ticketLock.lock();
			if(this.ticket>0) {
			try {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("当前进程为:"+Thread.currentThread().getName()+
						"剩余票数:"+this.ticket--);
			} finally {
				ticketLock.unlock();
			}
		  }
	   }		
	}
}

public class Test2 {
	public static void main(String[] args) {
		MyThread myThread=new MyThread();
		Thread thread=new Thread(myThread,"黄牛A");
		Thread thread2=new Thread(myThread,"黄牛B");
		Thread thread3=new Thread(myThread,"黄牛C");
		thread.start();
		thread2.start();
		thread3.start();
	}
}

 

你可能感兴趣的:(多线程同步的两大方式 Synchronized 和 lock的使用 及 synchronized对象锁与全局锁。什么时候是对象锁,什么时候是全局锁。)