java synchronized的运用

这几天被线程弄晕了

特地恶补了一下java的线程知识


synchronized关键字是可以实现一个类对象同一时间只被一个线程调用,其他线程要调用这个对象只能等正在调用的线程结束或停止(一般会用在停止状态,如果是结束的话直接用join()方法会更方便)才能获得对象


synchronized使用方法一:锁定对象方法

动手写代码,写了一个模拟买票的场景:

先写一个Tickets类

class Tickets {
	public Tickets() {
		// TODO Auto-generated constructor stub
	}

	int total_tickets = 30;

	void sell_tickets(String thread_name) {
		synchronized (this) {
			total_tickets--;
			System.out.println(thread_name + " sell a ticket, remains "
					+ total_tickets);
		}
	}
}
设置一共有30张票,
 sell_tickets(String thread_name)
会将线程名和剩余张数打印出来,注意sell_tickets()里面用了synchronized(this),表示这段代码同一时间只能被一个线程调用

Thread counter1 = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int i = 0; i < 10; i++) {
					tickets.sell_tickets("1");
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
		Thread counter2 = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int i = 0; i < 10; i++) {
					tickets.sell_tickets("2");
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
		Thread counter3 = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int i = 0; i < 10; i++) {
					tickets.sell_tickets("3");
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
		counter1.start();
		counter2.start();
		counter3.start();

新建1个Tickets类对象,3个counter线程,每个线程每隔一段时间就卖1张票,在Thread.sleep的时候就会让别的等待线程获得tickets.sell_ticket的使用权

结果如下:

1 sell a ticket, remains 29
3 sell a ticket, remains 28
2 sell a ticket, remains 27
1 sell a ticket, remains 26
2 sell a ticket, remains 25
3 sell a ticket, remains 24
2 sell a ticket, remains 23
1 sell a ticket, remains 22
3 sell a ticket, remains 21
2 sell a ticket, remains 20
1 sell a ticket, remains 19
3 sell a ticket, remains 18
2 sell a ticket, remains 17
1 sell a ticket, remains 16
3 sell a ticket, remains 15
2 sell a ticket, remains 14
3 sell a ticket, remains 13
1 sell a ticket, remains 12
2 sell a ticket, remains 11
3 sell a ticket, remains 10
1 sell a ticket, remains 9
2 sell a ticket, remains 8
1 sell a ticket, remains 7
3 sell a ticket, remains 6
2 sell a ticket, remains 5
1 sell a ticket, remains 4
3 sell a ticket, remains 3
2 sell a ticket, remains 2
3 sell a ticket, remains 1
1 sell a ticket, remains 0
可以看到,三个线程调用tickets对象并没有发生冲突


synchronized使用方法二:线程中锁定对象

这一次我们并不锁定Tickets类方法

只做一般的定义

class Tickets {
	public Tickets() {
		// TODO Auto-generated constructor stub
	}

	int total_tickets = 30;

	void sell_tickets(String thread_name) {
			total_tickets--;
			System.out.println(thread_name + " sell a ticket, remains "
					+ total_tickets);
	}
}

但我们在线程的runnable中使用synchronized将tickets对象同步

Thread counter1 = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int i = 0; i < 10; i++) {
					synchronized (tickets) {
						tickets.sell_tickets("1");
					}
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
同样能实现同步的效果




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。