package com.test.springboot.test;
/**
* 线程安全:多个线程共享一个全局变量,在做写的操作,可能会受到干扰,导致数据有问题,读的时候不会发生线程安全问题
* 使用场景:真正产生一个同一个全局变量
* 如何实现同步: synchronized 和lock
* 同步锁的使用条件:至少需要两个以上的线程,需要同步;多个线程想同步,必须使用同一把锁
*
* @author Administrator
* @date 2018/2/2 0002
*/
/**
* 创建自己的线程类
*/
class train01 extends Thread {
private static int count = 100;
/*private Object obj = new Object();*/
/**
* run()方法中定义要执行的任务
*/
@Override
public void run() {
while (count > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 出售火车票
*/
sale();
}
}
public void sale() {
/**同步代码块synchronized 包裹需要线程安全的问题
假如有两个线程访问:这个时候只有一个线程进行访问,必须拿到锁之后才可以访问
*/
/*synchronized (obj) {*/
synchronized (this) {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + "出售的票是第" + (100 - count + 1) + "张");
count--;
}
}
}
}
public class thread {
public static void main(String[] args) {
/**
* 创建线程对象
*/
train01 train01 = new train01();
Thread t1 = new Thread(train01, "01口");
Thread t2 = new Thread(train01, "02口");
t1.start();
t2.start();
}
}
同步代码块
1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块。其语法如下:
synchronized(obj){
//同步代码块
}
其中obj就是同步监视器,它的含义是:线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后,该线程会释放对该同步监视器的锁定。虽然java程序允许使用任何对象作为同步监视器,但 是同步监视器的目的就是为了阻止两个线程对同一个共享资源进行并发访问,因此通常推荐使用可能被并发访问的共享资源充当同步监视器
static同步函数:
/**
* 创建自己的线程类
*/
class train extends Thread {
private static int count = 100;
/**
* run()方法中定义要执行的任务
*/
@Override
public void run() {
while (count > 0) {
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 出售火车票
*/
sale();
}
}
/**
* 静态同步函数:在方法上加上synchronized static
* 不能使用this锁
*/
public static void sale() {
/**同步代码块synchronized 包裹需要线程安全的问题
假如有两个线程访问:这个时候只有一个线程进行访问,必须拿到锁之后才可以访问
*/
synchronized (test01.class) {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + "出售的票是第" + (100 - count + 1) + "张");
count--;
}
}
}
}
public class test01 {
public static void main(String[] args) {
/**
* 创建线程对象
*/
train train = new train();
Thread t1 = new Thread(train, "01口");
Thread t2 = new Thread(train, "02口");
t1.start();
t2.start();
}
}