这几天被线程弄晕了
特地恶补了一下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(); } } } });
同样能实现同步的效果
时间: 2024-10-08 01:32:35