_126_Java_线程同步

  • 线程安全原因

 当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。

  • 线程安全解决方法 

 对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。

  •  同步机制

 Java对于多线程的安全问题提供了专业的解决方式:

 

/*
 * 1、线程存在安全问题的原因
 * 由于一个线程在操作共享数据的过程中,未执行完毕的情况下,另外的线程参与进来,导致了共享数据存在安全问题。
 * 
 * 2、如何解决数据的安全问题
 * 必须让一个线程操作完共享数据之后,其他线程才有机会参与共享数据的操作。
 * 
 * 3、Java如何现成的安全,线程的同步机制
 * (1):同步代码块
	 * synchronized(同步监视器){
	 * 		//需要被同步的代码块(即为操作共享数据的代码)
	 * }
	 * 共享数据:多个线程共同操作的同一个数据(或者变量)。
	 * 
	 * 同步监视器:有一个类(可创建实例的类)的对象来充当。
	 哪一个线程获取此监视器(就是锁),谁就执行大括号里被同步的代码。所有的线程必须共用一把锁。
	 
	 *注:在实现的方式中,同步代码块的监视器可以使用this来充当。但是在继承Thread的方式中,慎用this。
	 
	 *
 * 
 * (2):同步方法
 * 将操作共享数据的方法声明为synchronized,即此方法为同步方法。
 * >>同步方法的锁:this
 * 
 * 4、线程同步的弊端:由于同一个时间内只有一个线程访问共享数据,效率变低。
 * 
 * 
 * */
public class _001_TestSynchronous {

	/* (1):同步代码块 */
	private static class Windows implements Runnable {
		private int tickets = 100;

		@Override
		public void run() {
			// TODO Auto-generated method stub
			Object object = new Object();
			while (true) {
// 实现Runnable,object由this来代替,this表示当前对象;继承Thread慎用。
				synchronized (object) {
					if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "售票,票号为:" + tickets--);
					} else {
						break;
					}
				}

			}
		}
	}

	private static class WindowsA extends Thread {
		private static int tickets = 100;
		private static Object object = new Object();

		@Override
		public void run() {
			// TODO Auto-generated method stub
			Object object = new Object();
			while (true) {
// 实现Runnable,object由this来代替,this表示当前对象;继承Thread时,this慎用。
				synchronized (object) {
					if (tickets > 0) {

System.out.println(Thread.currentThread().getName() + "售票,票号为:" + tickets--);
					} else {
						break;
					}
				}

			}
		}
	}

	/* (2):同步方法 */
	private static class WindowsB implements Runnable {
		private int tickets = 700;//取数大一点
		@Override
		public void run() {
			while (tickets>0) {
				show();
			}
				
		}
		public synchronized void show() {
			if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "售票,票号为:" + tickets--);
			}
		}
	}

	public static void test() {
		_001_TestSynchronous.Windows win = new _001_TestSynchronous.Windows();
		Thread t = new Thread(win);
		Thread tA = new Thread(win);
		Thread tB = new Thread(win);

		t.setName("win");
		tA.setName("win1");
		tB.setName("win2");

		t.start();
		tA.start();
		tB.start();
	}

	public static void testA() {
		_001_TestSynchronous.WindowsA win = new _001_TestSynchronous.WindowsA();
		_001_TestSynchronous.WindowsA winA = new _001_TestSynchronous.WindowsA();
		_001_TestSynchronous.WindowsA winB = new _001_TestSynchronous.WindowsA();

		win.start();
		winA.start();
		winB.start();
	}
	
	public static void testB() {
		_001_TestSynchronous.WindowsB win = new _001_TestSynchronous.WindowsB();
		Thread t = new Thread(win);
		Thread tA = new Thread(win);
		Thread tB = new Thread(win);

		t.setName("win");
		tA.setName("win1");
		tB.setName("win2");

		t.start();
		tA.start();
		tB.start();
	}

	public static void main(String[] args) {
		/*
		 * test();
		testA();
		*/
		testB();
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值