1、synchronized
synchronized分类锁和对象锁;
package com.study.syn;
/**
* Created by Administrator on 2019/7/28.
*/
public class SynTest {
public synchronized void syn1(){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("syn1....................."+ Thread.currentThread().getName());
}
public static synchronized void synStatic(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("syn static.....................");
}
}
代码中syn1就是属于对象锁,另外方法中的synchronized 代码块也是属于对象锁,而静态变量修饰的synStatic就是属于类锁;
对象锁 锁的是该类SynTest的实例对象;
类锁 锁的是SynTest的类对象;当使用Spring管理bean时,一般都是注入的单例bean,通常来说就是锁的SynTest这个单实例;
测试对象锁:
1、新建个线程类
package com.study.syn;
/**
* Created by Administrator on 2019/7/28.
*/
public class Threads extends Thread{
SynTest synTest;
public Threads(SynTest synTest){
this.synTest = synTest;
}
@Override
public void run() {
synTest.syn1();
}
}
2、main方法来测试这个对象锁;
package com.study.syn;
/**
* Created by Administrator on 2019/7/28.
*/
public class Test {
public static void main(String[] args) {
SynTest synTest1 = new SynTest();
//SynTest synTest2 = new SynTest();
//SynTest synTest3 = new SynTest();
//SynTest synTest4 = new SynTest();
Threads t1 = new Threads(synTest1);
Threads t2 = new Threads(synTest1);
Threads t3 = new Threads(synTest1);
Threads t4 = new Threads(synTest1);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
3、执行main方法后,运行结果:
每隔两秒打印
syn1.....................Thread-0
syn1.....................Thread-3
syn1.....................Thread-2
syn1.....................Thread-1
结果:说明:syn1方法是被锁住了的,4个线程访问syn1方法,只能依次等待锁放开;此处是竞争的synTest1这个实例对象;
4、测试类的多个实例对象
package com.study.syn;
/**
* Created by Administrator on 2019/7/28.
*/
public class Test {
public static void main(String[] args) {
SynTest synTest1 = new SynTest();
SynTest synTest2 = new SynTest();
SynTest synTest3 = new SynTest();
SynTest synTest4 = new SynTest();
Threads t1 = new Threads(synTest1);
Threads t2 = new Threads(synTest2);
Threads t3 = new Threads(synTest3);
Threads t4 = new Threads(synTest4);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
此处意思是4个线程去跑4个对象实例,这样的结果就是在2秒后相继打印出
syn1.....................Thread-1
syn1.....................Thread-0
syn1.....................Thread-2
syn1.....................Thread-3
说明这4个线程竞争的不是一个锁,如果说是竞争的一个锁的话,打印的结果应该是每隔2秒打印一个输出;
测试类锁:
1、把Threads线程类中的run方法中的调用方法改为 :synTest.synStatic();运行测试对象锁的2种main;2种测试结果是一致的,都是在一秒后输出一条打印信息,说明2种方式竞争的锁都是同一个锁;
以上就是对象锁的解释,个人记录------------------------分割线----------------------------
2、volatile
volatile关键字:个人感觉不好解释(其实解释不来),只知道这个用处是什么,变量被volatile修饰后,每次要访问这个被修饰的变量时,都是通过去内存读取该变量,在读取方面来说是比较安全的(前提是一个线程去写,其他的线程去读);volatile是非线程安全的,即当多个线程去修改该变量时,可能会存在错误,不会像Atomic包下面的CAS方式,修改值时去compare;说了这么多,代码测试
package com.study.volatiles;
/**
* Created by Administrator on 2019/7/28.
*/
public class ThreadVolatile implements Runnable{
private volatile int anInt = 0;
@Override
public void run() {
try {
System.out.println("线程名字:"+Thread.currentThread().getName()+"---执行加的操作:加之前的值"+anInt);
anInt = anInt + 2;
Thread.sleep(100);
System.out.println("线程名字:"+Thread.currentThread().getName()+"---执行加的操作:加之后的值为"+anInt);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
通过ThreadVolatile 的一个实例对象来创建多个线程
package com.study.volatiles;
/**
* Created by Administrator on 2019/7/28.
*/
public class VolatileTest {
public static void main(String[] args) {
ThreadVolatile threadVolatile = new ThreadVolatile();
Thread thread1 = new Thread(threadVolatile);
Thread thread2 = new Thread(threadVolatile);
Thread thread3 = new Thread(threadVolatile);
Thread thread4 = new Thread(threadVolatile);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
如果说volatile 修饰的anInt是原子性的,那么每个线程对于修改他的前后值应该是只差2的;运行结果就证实是非原子性的,即volatile修饰的变量时非线程安全的;
volatile适用的地方:一个线程去写修饰的变量,其他的线程去读这个变量:那么是属于可行的;
3、ThreadLocal
ThreadLocal是属于线程级变量;相当于使用ThreadLocal来创建的变量,比如一个实现runable的类的实例,被创建了5个线程,这五个线程中访问的是一个类实例中的变量a,但是ThreadLocal方式就会使这5个线程各自拥有一个独立的线程变量a,他们的取值,赋值都是独立的,都不会有影响,查阅网上有句话说的是:ThreadLocal是以空间换时间,每个线程创建一个副本,来达到同时访问,而互不冲突;synchronized是以时间换空间,线程获取锁(等待执行),达到线程安全;
以上通过学习后,纯手码,有人看到不对可直接开喷,越喷越进步,继续努力。。。。。。。。。。。。。。。