Java用同步代码块实现线程同步

Java用同步代码块实现线程同步:

本文示例卖票的,三张票,四个窗口出售

testsale1为四个线程处理同一个对象,sale1内有两个方法,可供run方法调用,一个是未使用同步代码块的方法,一个是使用同步代码块的方法

testsale2为四个线程处理四个对象,对象不同,但可以同步,直接将同步代码块写入run方法

Thread.start()和Thread.run()的区别:

start是进入就绪不一定去执行,该线程执行时会自动调用内部的run方法。

调用run的话会直接执行。自动将当前线程变为主线程,并没有实现分线程。

这一点区别可以使用Thread.currentThread().getName()进行验证


废话不多说,关于卖票多线程实现方法和具体解释看代码

如果看不出来,连续多运行几次就能看出区别

注释表示可选的验证

package ticket;

public class ticket {
	public static void main(String[] args) {
		testsale1();
		testsale2();
		
	}

	/**
	 * 测试sale1的方法 多个线程处理同一对象 实现线程同步
	 */
	public static void testsale1() {
		sale1 s = new sale1();
		Thread t1 = new Thread(s, "windows 1");
		Thread t2 = new Thread(s, "windows 2");
		Thread t3 = new Thread(s, "windows 3");
		Thread t4 = new Thread(s, "windows 4");
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}

	/**
	 * 测试sale2的方法 多个线程处理不同对象 实现线程同步
	 */
	public static void testsale2() {
		sale2 s1 = new sale2();
		sale2 s2 = new sale2();
		sale2 s3 = new sale2();
		sale2 s4 = new sale2();

		Thread t1 = new Thread(s1, "windows 1");
		Thread t2 = new Thread(s2, "windows 2");
		Thread t3 = new Thread(s3, "windows 3");
		Thread t4 = new Thread(s4, "windows 4");

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

/**
 * 一个类可以包含多个类,至少一个是public 下面类实现的是 使用同步代码块的多线程和没有使用同步代码块的多线程区别
 * 使用的可以确保进入该代码块的只有一个线程 没有使用的不能保证进入该代码快的是一个线程
 * 
 * @author Administrator
 *
 */
class sale1 implements Runnable {
	static int remainticket = 3;

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// saleTicket();
		sysale();
	}

	/**
	 * 没使用同步代码快标记的方法 该方法,可导致线程不稳定,输出结果不一致
	 */
	private void saleTicket() {
		// TODO Auto-generated method stub
		if (remainticket > 0) {
			remainticket--;
			System.out.println(Thread.currentThread().getName() + "    " + remainticket);
			// remainticket--;
		} else {
			System.out.println(Thread.currentThread().getName() + "    " + "no ticket");
		}
	}

	/**
	 * 使用同步代码块控制的方法 可以保证线程执行时只有一个线程调用该方法
	 */
	public synchronized void sysale() {
		if (remainticket > 0) {
			remainticket--;
			System.out.println(Thread.currentThread().getName() + "    " + remainticket);
			// remainticket--;
		} else {
			System.out.println(Thread.currentThread().getName() + "    " + "no ticket");
		}
	}
}

/**
 * 一个类可以包含多个类,至少一个是public 下面类实现的是 重写run方法在方法内实现同步代码块
 * 
 * @author Administrator
 *
 */
class sale2 implements Runnable {
	static int remainticket = 3;

	/**
	 * 将同步代码块直接写入run方法 synchronized (实现同步代码块的类名.class)
	 */
	@Override
	public void run() {
		// TODO Auto-generated method stub
		synchronized (sale2.class) {
			if (remainticket > 0) {
				remainticket--;
				System.out.println(Thread.currentThread().getName() + "    " + remainticket);
				// remainticket--;
			} else {
				System.out.println(Thread.currentThread().getName() + "    " + "no ticket");
			}
		}
	}

}





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值