一、线程安全
- 概念
当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全的。 - synchronized
能在任意对象及方法上加锁,而加锁段代码称为互斥区
或临界值。
例子:
没有加synchorized修饰的方法
package com.Thread.Sychronized;
public class Sychronized_Test extends Thread{
private int State=0;
public void run() {
State++;
System.out.println("name: "+this.currentThread().getName()+" State : "+State);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Sychronized_Test SychronizedThread=new Sychronized_Test();
Thread thread1= new Thread(SychronizedThread,"thread1");
Thread thread2= new Thread(SychronizedThread,"thread2");
Thread thread3= new Thread(SychronizedThread,"thread3");
Thread thread4= new Thread(SychronizedThread,"thread4");
Thread thread5= new Thread(SychronizedThread,"thread5");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
}
运行结果:
第一次:
name: thread1 State : 1
name: thread2 State : 4
name: thread3 State : 2
name: thread4 State : 3
name: thread5 State : 5
第二次:
name: thread3 State : 2
name: thread1 State : 1
name: thread2 State : 3
name: thread5 State : 5
name: thread4 State : 5
总结:由运行结果可看来没有加synchorized
修饰的方法的在单列情况下会表现出不正确的行为
加synchorized修饰的方法
package com.Thread.Sychronized;
public class Sychronized_Test extends Thread{
private int State=0;
public synchronized void run() {
State++;
System.out.println("name: "+this.currentThread().getName()+" State : "+State);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Sychronized_Test SychronizedThread=new Sychronized_Test();
Thread thread1= new Thread(SychronizedThread,"thread1");
Thread thread2= new Thread(SychronizedThread,"thread2");
Thread thread3= new Thread(SychronizedThread,"thread3");
Thread thread4= new Thread(SychronizedThread,"thread4");
Thread thread5= new Thread(SychronizedThread,"thread5");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
}
运行结果:
第一次
name: thread1 State : 1
name: thread3 State : 2
name: thread2 State : 3
name: thread4 State : 4
name: thread5 State : 5
第二次
name: thread1 State : 1
name: thread3 State : 2
name: thread2 State : 3
name: thread4 State : 4
name: thread5 State : 5
总结:当多个线程访问SychronizedTest的run方法时,以排队的方式进行处理(排队:按照CPU分配的先后顺序而定),想执行互斥区,首先尝试获得锁:
- 拿 到 锁:执行synchronized代码体的内容。
- 拿不到锁:不断地尝试获得这把锁,直到拿到为止,存在多个线程同时去竞争锁的问题。