1、线程开启后并不会立即执行,由CPU来分配。
2、并行不一定比串行更快,要注意上下文切换和锁的开销。
3、Callable可以定义返回值,可以抛出异常。
4、Runnable接口使用静态代理。Thread类本身就实现了Runnable接口。
将实现了Runnable接口的线程类的实例作为参数传入Thread的构造方法中,将成为一个代理对象target并由Thread类实例代理。
执行Thread实例的start方法,实际执行的就是线程类的run方法。
5、扩展,创建线程时,使用Lamda表达式来替代匿名内部类。
Lamda表达式适用于函数式接口(只有一个抽象方法的接口)
6、synchronized修饰方法的时候,锁的对象是this;修饰同步块的时候,锁的对象是同步块括号中的对象。
锁的对象,是需要增删改的对象。
7、ReentrantLock,Lock的一个典型实现类,可重入锁,显示的锁,需要手动的开关,不能锁方法。
8、自旋锁,相较于普通的互斥锁,会在获取不到锁的时候不会进入阻塞状态,而是开始循环,再一段时间内(一般设置循环次数)多次尝试获取锁。
9、CAS,Compare And Swap,是一种无锁编程的思想,也是一种乐观锁的实现。通过在交换时,比较线程内的oldvalue是否和当前加锁对象的value一致来判断本次交换能否提交。一般由具体的工具类实现,例如AtomicInteger类。要特别注意,Compare和Swap这两个操作要同步,否则还是会有线程安全问题。
整理代码:
1)典型的多线程,类本身实现Runnable接口:
public class ThreadStudy implements Runnable{
private int counter=10;
public static void main(String args[]){
ThreadStudy ts = new ThreadStudy();
Thread t1 = new Thread(ts);
t1.start();
}
public void run() {
synchronized (this){
while(this.counter>0){
this.counter--;
System.out.println(Thread.currentThread().getName()+"计数器的值为:"+ this.counter);
}
}
}
}
2)外部类实现:
public class ThreadStudy {
static int counter=10;
public static void main(String args[]){
Thread t1 = new Thread(new MyThread());
t1.start();
}
}
class MyThread implements Runnable{
public void run() {
while(ThreadStudy.counter>0){
ThreadStudy.counter--;
System.out.println(Thread.currentThread().getName()+"计数器的值为:"+ ThreadStudy.counter);
}
}
}
3)静态内部类:
public class ThreadStudy {
static int counter=10;
public static void main(String args[]){
Thread t1 = new Thread(new MyThread());
t1.start();
}
static class MyThread implements Runnable{
public void run() {
while(ThreadStudy.counter>0){
ThreadStudy.counter--;
System.out.println(Thread.currentThread().getName()+"计数器的值为:"+ ThreadStudy.counter);
}
}
}
}
4)匿名内部类实现:
public class ThreadStudy {
static int counter=10;
public static void main(String args[]){
Thread t1 = new Thread(new Runnable() {
public void run() {
while(ThreadStudy.counter>0){
ThreadStudy.counter--;
System.out.println(Thread.currentThread().getName()+"计数器的值为:"+ ThreadStudy.counter); }
}
});
t1.start();
}
}
5)Lambda表达式实现:
public class ThreadStudy {
static int counter=10;
public static void main(String args[]){
new Thread(()-> {
while(ThreadStudy.counter>0){
ThreadStudy.counter--;
System.out.println(Thread.currentThread().getName()+"计数器的值为:"+ ThreadStudy.counter); }
}).start();
}
}
6)互斥锁样例:
public class LockStudy implements Runnable{
private static Object o1 = new Object();
private static Object o2 = new Object();
private boolean flag = true;
public LockStudy(boolean flag) {
this.flag = flag;
}
public static void main(String args[]){
LockStudy ts1 = new LockStudy(true);
LockStudy ts2 = new LockStudy(false);
Thread t1 = new Thread(ts1);
Thread t2 = new Thread(ts2);
t1.start();
t2.start();
}
public void run(){
if(flag){
synchronized (o1){
System.out.println(Thread.currentThread().getName()+"线程获取了o1");
synchronized (o2){
System.out.println(Thread.currentThread().getName()+"线程获取了o2");
}
}
}{
synchronized (o2){
System.out.println(Thread.currentThread().getName()+"线程获取了o2");
synchronized (o1){
System.out.println(Thread.currentThread().getName()+"线程获取了o1");
}
}
}
}
}
下一步关注:分布式锁
volatile关键字:当一个多线程的共享变量被volatile修饰时,该变量若发生修改,会立刻保存在主内存中,并禁止了指令重排,保证了多线程对共享变量的可见性和程序执行的有序性。但没有实现原子性。
transient序列化在内存中