package Lesson4;
import java.util.ArrayList;
import java.util.List;
public class SafeThread {
public static int COUNT;
//默认0
public static void main(String[] args) {
//建20个线程,一直++,打印20万
//3.通过公关对象锁定
Object object=new Object();
for(int i=0;i<20;i++) {
new Thread(new Runnable() {
@Override
public void run() {
for(int j=0;j<10000;j++){
// COUNT++;
//count不是原子的,还有可见性,因为可见性体现了非原子
//第一种静态 类对象锁定
//锁类对象
increment();
//执行到这行代码才排队,其他地方还是有时间片轮转
//同步指的是increment()同步 就是执行这个方法才互斥,不管是哪个线程获得锁加一次,
// 看时间片轮转,就释放锁
decrement();
//第二种 实例对象锁定
/*
synchronized (object){
//锁定的这个对象的所有方法锁定,等待
COUNT++;
//锁公共实例对象
}
*/
//其他线程进不来一直等
}
}
}).start();
}
//Thread.sleep(1000),不保险,不知道10秒钟执行完没有
while(Thread.activeCount()>2){
Thread.yield();
}
System.out.println(COUNT);
List<Integer> list=new ArrayList<>();
for(int i=0;i<20;i++) {
final int k=i;
new Thread(new Runnable() {
@Override
public void run() {
for(int j=0;j<10000;j++){
list.add(k*10000+j);
}
}
}).start();
}
while (Thread.activeCount()>1){
Thread.yield();
}
System.out.println(list.size());
//抛异常数组下标越界
}
//1.静态同步方法锁定对象
//关键字可以放在public之前,也可以放在public之后
/* public synchronized static void increment(){
//锁的对象是类
COUNT++;
}
*/
//上下等价
public static void increment(){
//如果这里加代码,上下就不等价了
//锁的对象是类
synchronized (SafeThread.class){
COUNT++;
//执行到这个代码才获取锁
//同步方法不结束就一直获取这个锁
}
//synchronized 锁的是对象,不是代码块,这个对象所有同步的地方被锁定
}
//同步方法:同步互斥方法
//一个线程进来,获取这把锁,其他线程进来会等着,等用完了会释放这个锁,别的线程才能获取
//对class加锁,每个线程进来都要申请获取资源,
public synchronized static void decrement(){
COUNT--;
}
//锁已经被锁定了,照样等,因为锁的都是类对象
//2.实例对象锁定 锁定当前调用该方法的对象
public synchronized void a(){
}
//上下等价
public void b(){
synchronized (this){
}
}
}