这几天被线程弄晕了
特地恶补了一下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();
}
}
}
});同样能实现同步的效果
本文通过实例深入解析Java中的synchronized关键字及其使用方法,包括锁定对象和线程中锁定对象两种方式,详细展示了如何实现线程同步,确保在多线程环境下资源的安全访问。
585

被折叠的 条评论
为什么被折叠?



