自定义线程和线程同步原理不懂的可以先看下面2个链接资料
Java之自定义线程的2种方式:https://blog.csdn.net/qq_38225558/article/details/82118862
Java之线程安全问题的3种处理方式(通过线程同步):https://blog.csdn.net/qq_38225558/article/details/82154321
线程同步:完成多线程售票实例 ==> 假设存在2个窗口售票
第1种方式:自定义线程继承Thread类 同步方法 ==> 使用synchronized 修饰方法
public class Demo1{
public static void main(String[] args) {
Station station = new Station();
TicketThread t1 = new TicketThread(station);
TicketThread t2 = new TicketThread(station);
t1.start();
t2.start();
}
}
class Station{
private static int tickets = 20;//记录车票的数量 使用static目的:确保2个窗口是共同在出售这20张票而不是这2个窗口各自出售20张 共出售40张
//定义一个买票的方法
public synchronized void getTicket(){
if(tickets>0){
System.out.println("车票还剩: "+ (--tickets) + "张 !");
}
}
}
class TicketThread extends Thread{
private Station station;
public TicketThread(Station station) {
this.station = station;
}
@Override
public void run() {
while(true){
station.getTicket();
}
}
}
运行结果图:
第2种方式:自定义线程继承Thread类 同步代码块 synchronized(被加锁的对象){ 代码 }
public class Demo2{
public static void main(String[] args) {
Station station = new Station();
TicketThread t1 = new TicketThread(station);
TicketThread t2 = new TicketThread(station);
t1.start();
t2.start();
}
}
class Station{
private static int tickets = 20;//记录车票的数量 使用static目的:确保2个窗口是共同在出售这20张票而不是这2个窗口各自出售20张 共出售40张
//定义一个买票的方法
public void getTicket(){
synchronized (this) {
if(tickets>0){
System.out.println("车票还剩: "+ (--tickets) + "张 !");
}
}
}
}
class TicketThread extends Thread{
private Station station;
public TicketThread(Station station) {
this.station = station;
}
@Override
public void run() {
while(true){
station.getTicket();
}
}
}
第3种方式:自定义线程继承Thread类 锁机制lock
public class Demo3 {
public static void main(String[] args) {
Station station = new Station();
TicketThread t1 = new TicketThread(station);
TicketThread t2 = new TicketThread(station);
t1.start();
t2.start();
}
}
class Station{
private static int tickets = 20;//记录车票的数量 使用static目的:确保2个窗口是共同在出售这20张票而不是这2个窗口各自出售20张 共出售40张
// 1.创建Lock实现类的对象 注意:需在getTicket()方法外执行,如果在getTicket()方法里执行,在getTicket()方法被调用的时候就会被创建很多ReentrantLock对象,即出现很多锁
ReentrantLock lock = new ReentrantLock();
//定义一个买票的方法
public void getTicket(){
// 2.使用Lock对象的lock方法加锁
lock.lock();
if(tickets>0){
System.out.println("车票还剩: "+ (--tickets) + "张 !");
}
// 3.使用Lock对象的unlock方法解锁
lock.unlock();
}
}
class TicketThread extends Thread{
private Station station;
public TicketThread(Station station) {
this.station = station;
}
@Override
public void run() {
while(true){
station.getTicket();
}
}
}
第4种方式:自定义线程 实现Runnable接口 锁机制lock
public class Demo4 {
public static void main(String[] args) {
Station station = new Station();
TicketThread ticketThread1 = new TicketThread(station);
TicketThread ticketThread2 = new TicketThread(station);
Thread t1 = new Thread(ticketThread1);
Thread t2 = new Thread(ticketThread2);
t1.start();
t2.start();
}
}
class Station{
private static int tickets = 20;//记录车票的数量 使用static目的:确保2个窗口是共同在出售这20张票而不是这2个窗口各自出售20张 共出售40张
// 1.创建Lock实现类的对象 注意:需在getTicket()方法外执行,如果在getTicket()方法里执行,在getTicket()方法被调用的时候就会被创建很多ReentrantLock对象,即出现很多锁
ReentrantLock lock = new ReentrantLock();
//定义一个买票的方法
public void getTicket(){
// 2.使用Lock对象的lock方法加锁
lock.lock();
if(tickets>0){
System.out.println("车票还剩: "+ (--tickets) + "张 !");
}
// 3.使用Lock对象的unlock方法解锁
lock.unlock();
}
}
class TicketThread implements Runnable{
private Station station;
public TicketThread(Station station) {
this.station = station;
}
@Override
public void run() {
while(true){
station.getTicket();
}
}
}
第5种方式:自定义线程 实现Runnable接口 同步方法 ==> 使用synchronized 修饰方法
public class Demo5 {
public static void main(String[] args) {
Station station = new Station();
TicketThread ticketThread1 = new TicketThread(station);
TicketThread ticketThread2 = new TicketThread(station);
Thread t1 = new Thread(ticketThread1);
Thread t2 = new Thread(ticketThread2);
t1.start();
t2.start();
}
}
class Station{
private static int tickets = 20;//记录车票的数量 使用static目的:确保2个窗口是共同在出售这20张票而不是这2个窗口各自出售20张 共出售40张
//定义一个买票的方法
public synchronized void getTicket(){
if(tickets>0){
System.out.println("车票还剩: "+ (--tickets) + "张 !");
}
}
}
class TicketThread implements Runnable{
private Station station;
public TicketThread(Station station) {
this.station = station;
}
@Override
public void run() {
while(true){
station.getTicket();
}
}
}
第6种方式:自定义线程 实现Runnable接口 同步代码块 synchronized(被加锁的对象){ 代码 }
public class Demo6 {
public static void main(String[] args) {
Station station = new Station();
TicketThread ticketThread1 = new TicketThread(station);
TicketThread ticketThread2 = new TicketThread(station);
Thread t1 = new Thread(ticketThread1);
Thread t2 = new Thread(ticketThread2);
t1.start();
t2.start();
}
}
class Station{
private static int tickets = 20;//记录车票的数量 使用static目的:确保2个窗口是共同在出售这20张票而不是这2个窗口各自出售20张 共出售40张
//定义一个买票的方法
public void getTicket(){
synchronized (this) {
if(tickets>0){
System.out.println("车票还剩: "+ (--tickets) + "张 !");
}
}
}
}
class TicketThread implements Runnable{
private Station station;
public TicketThread(Station station) {
this.station = station;
}
@Override
public void run() {
while(true){
station.getTicket();
}
}
}