JAVA基础 多线程-线程安全 synchronized关键字与Lock接口

  • 同步代码块与同步方法


package demo;

import javax.swing.plaf.synth.SynthColorChooserUI;

public class Test1 {

	public static void main(String[] args) {

		MyRunable r = new MyRunable();
		
		Thread t0 = new Thread(r);
		Thread t1 = new Thread(r);
		Thread t2 = new Thread(r);
		t0.start();
		t1.start();
		t2.start();
		
	
		
	}

}

/*
 * 线程不安全的
 * Thread-0: 出售第1张票。
	Thread-1: 出售第0张票。
	Thread-2: 出售第-1张票。
 * 
 */
//class MyRunable implements Runnable{
//	int tickets = 100;
//	public void run() {
//		while(tickets>0) {
//			try {
//				Thread.sleep(1);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//			System.out.println(
//					Thread.currentThread().getName()+": 出售第"+(tickets--)+"张票。");
//		}
//	}
//	
//}

/*
 * 使用同步代码块保证线程安全
 * synchronized
 */

//class MyRunable implements Runnable{
//	int tickets = 100;
//	Object lock = new Object();//对象锁,synchronized关键字需要一个对象作为锁
//	
//	public void run() {
//		synchronized (lock) {
//			while(tickets>0) {
//				try {
//					Thread.sleep(1);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
//				System.out.println(
//						Thread.currentThread().getName()+": 出售第"+(tickets--)+"张票。");
//			}
//		}
//	}
//}

/*
 * synchronized传入this关键字实现对象作为锁
 */
//class MyRunable implements Runnable{
//	int tickets = 100;
//	public void run() {
//		synchronized (this) {
//			while(tickets>0) {//对象锁可以传入this,runnable类的实现对象
//				try {
//					Thread.sleep(1);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
//				System.out.println(
//						Thread.currentThread().getName()+": 出售第"+(tickets--)+"张票。");
//			}
//		}
//	}
//}


/*
 * 类静态变量,synchronized传入该类作为锁
 */
//class MyRunable implements Runnable{
//	private static int tickets = 100;//静态变量
//	public void run() {
//		synchronized (MyRunable.class) {//锁是该类
//			while(tickets>0) {
//				try {
//					Thread.sleep(1);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
//				System.out.println(
//						Thread.currentThread().getName()+": 出售第"+(tickets--)+"张票。");
//			}
//		}
//	}
//}


/*
 * 同步方法public synchronized void method(){}
 */
//
//class MyRunable implements Runnable{
//	int tickets = 100;
//	public void run() {
//		while(true) {
//			this.method();
//		}
//	}
//	
//	public synchronized void method() {
//		if(tickets>0) {
//			try {
//				Thread.sleep(1);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}	
//			System.out.println(
//					Thread.currentThread().getName()+": 出售第"+(tickets--)+"张票。");
//		}else {
//			System.out.println("票卖完了...");
//			System.exit(0);
//		}
//	}
//}



class MyRunable implements Runnable{
	int tickets = 100;
	public void run() {
		while(true) {
			this.method();
		}
	}
	
	public synchronized void method() {
		if(tickets>0) {
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}	
			System.out.println(
					Thread.currentThread().getName()+": 出售第"+(tickets--)+"张票。");
		}else {
			System.out.println("票卖完了...");
			System.exit(0);
		}
	}
}

  • 使用Lock接口来保证线程安全
package demo;

import java.util.concurrent.locks.ReentrantLock;

public class Test2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		TicketTask tt = new TicketTask();
		Thread t1 = new Thread(tt);
		Thread t2 = new Thread(tt);
		t1.start();
		t2.start();
	}

}

class TicketTask implements Runnable {
	int tickets = 100;
	ReentrantLock lock = new ReentrantLock();

	public void run() {
		while (true) {
			lock.lock();
			if (tickets > 0) {
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + ": 出售第" + (tickets--) + "张票。");
			} 

			lock.unlock();
		}
	}

}



猜你喜欢

转载自blog.csdn.net/alexzt/article/details/80163957