1.synchronized是java中的关键字,是一种同步锁,他修饰的对象有以下几种
- 修饰一个代码块,被修饰的代码块被称为同步语句,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象
- 修饰一个方法,被修饰的方法称为同步方法,其作用范围是整个方法,作用的对象是调用这个方法的对象
虽然可以使用synchronized来定义方法,但synchronized并不属于方法定义的一部分,因此,synchronized关键字不能被继承。如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况并不是同步的,而必须显示地在子类的方法中加上synchronized关键字才可以,当然,还可以再子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,但子类调用了父类的同步方法,因此子类的方法相当于同步方法 - 修饰一个类,其作用的范围是整个静态方法,作用的对象是这个类的所有对象
- 修饰一个类,其作用的范围是sycnchronized后面括号括起来的部分,作用主的对象是这个类的所有对象
2.多线程编程步骤 - 第一步创建资源类,在资源类创建属性和方法
- 第二部创建多个线程,调用资源类的操作方法
- Thread构造方法摘要
3.卖票案例 - 资源类
package com.minjiang.entity;
/**
* @auther guannw
* @create 2021/7/22 15:04
*/
public class Ticket {
//票数
private int number = 30;
//操作方法:卖票
public synchronized void sale(){
//判断当前是否还有票售卖
if(number > 0){
System.out.println(Thread.currentThread().getName()+":卖出:"+number--+"剩下:"+number );
}
}
}
- 创建多个线程使用资源类
package com.minjiang.sync;
import com.minjiang.entity.Ticket;
/**
* @auther guannw
* @create 2021/7/22 15:03
*/
//第一步创建资源类,定义属性和操作方法
public class SaleTicket {
//第二步 创建多个线程 调用资源类操作方法
public static void main(String[] args) {
//创建ticket对象
Ticket ticket = new Ticket();
new Thread(new Runnable() {
@Override
public void run() {
//调用卖票方法
for ( int i = 0; i < 40 ; i++){
ticket.sale();
}
}
},"aa").start();
new Thread(new Runnable() {
@Override
public void run() {
//调用卖票方法
for ( int i = 0; i < 40 ; i++){
ticket.sale();
}
}
},"bb").start();
new Thread(new Runnable() {
@Override
public void run() {
//调用卖票方法
for ( int i = 0; i < 40 ; i++){
ticket.sale();
}
}
},"cc").start();
}
}
测试结果可以看出,加上synchronized后操作方法只能同时被一个线程操作,也就是synchronized在被一个线程操作的时候就会加锁,操作结束之后就会释放锁