Java—买票窗口

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。


方式一:使用Runnable接口

/**
 * 例子:创建三个窗口买票,总票数为100张 ——> 使用实现Runnable接口的方式
 */
class Window1 implements Runnable{
    private int ticket = 10000;

    @Override
    public void run() {

        while(true){

            if(ticket > 0){
                System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket);
                ticket--;
            }else {
                break;
            }

        }

    }
}

public class WindowTest {
    public static void main(String[] args) {
        Window1 w = new Window1();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

方式二:使用线程同步机制(线程安全处理Synchronized,只有一个锁)

线程同步的方式有两种:

  方式1:同步代码块

  方式2:同步方法


使用同步代码块

public class ThreadTest {
	public static void main(String[] args) {
		Ticket t = new Ticket();
		
		Thread th1 = new Thread(t);
		Thread th2 = new Thread(t);
		Thread th3 = new Thread(t);
		
		th1.setName("窗口1");
		th2.setName("窗口2");
		th3.setName("窗口3");
		
		th1.start();
		th2.start();
		th3.start();
	}
}

class Ticket implements Runnable{
	// 定义票根
	int ticket = 100;


	Object lock = new Object();
	@Override
	public void run() {

		while(true){
			
			// synchronized中的的参数可以为任意对象
			synchronized (lock) {
				if(ticket > 0){
					// 模拟选座的操作
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket);
					ticket--;
				}else{
					break;
				}
			}
			
		}
		
	}
	
}

使用同步方法

public class ThreadTest {
	public static void main(String[] args) {
		Ticket t = new Ticket();
		
		Thread th1 = new Thread(t);
		Thread th2 = new Thread(t);
		Thread th3 = new Thread(t);
		
		th1.setName("窗口1");
		th2.setName("窗口2");
		th3.setName("窗口3");
		
		th1.start();
		th2.start();
		th3.start();
	}
}

class Ticket implements Runnable{
	// 定义票根
	int ticket = 100;

	@Override
	public void run() {
		while(true){
			// 同步方法
			boolean method = method();
			if(method){
				break;
			}
		}
	}
	
	// 同步方法中的锁对象是 this
	// 静态同步方法中的锁对象是 类名.class
	public synchronized boolean method() {
		boolean flag = false;
		
		if(ticket > 0){
			// 模拟选座的操作
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket);
			ticket--;
		}else{
			flag = true;
		}
		
		return flag;
	}
	
}
原文地址:https://www.cnblogs.com/nadou/p/13984451.html