写在前面
一切技术都是纸老虎,技术就是一层膜,捅破了就什么也不是
多线程两种实现方式
继承 Thread 类,实现 run 方法将需要多线程启动的功能代码放在 run 方法内 该方式有 isinterrupted 标志位,
可以根据该标志位在另一个能够获取到该线程的代码块中that.interrupt 实现中断,但是是否真的中断则由that线程决定
实现 runnable 接口,覆写 run 方法将需要多线程启动的功能代码放在 run 方法内,注意这里没有 isInterrupted 标志位
实际上在一个线程中停止另一个线程可以用 concurrent 包中的 cancel 方法,这个 跟 python 简直一毛一样啊啊啊
ExecutorService 接口下固定大小线程池 (Fixed),动态变化(Cached) , 以及只有单个(Single)线程的 线程池
// t1.start() 永远使用 start --》 start0 (本地方法) 去启动线程 而非 调用 run 方法
// 这里记得 t1.join() 是等待t1线程执行完成才会继续往下执行
// t1.setDaemon(true) 设置为守护线程,也就是不那么重要的,JVM 在所有非守护线程执行完成后就会退出,垃圾回收就是一个守护线程
// 虽然我们以后使用 concurrent 包来进行并发,但是基础原理一定要掌握牢固
// 进程 六种状态
new | running | blocking | waiting | timed waiting|terminiated
Thread 常用方法
构造方法 Thread(Runnable target,String name)
静态方法:
Thread.currentThread().getName()
Thread.sleep(1000) // java 中 单位是毫秒 所以 1000ms = 1 s,python 中直接是 秒
线程安全同步机制 synchronized 同步代码快, 同步方法,可重入锁,可重入读写锁
加入 synchronized 同步方法, synchronized 这个方式不如 可重入锁安全,被synchronized修饰的要么获得锁,要么永远等待下去
public class Counter {
private int value;
public synchronized void inc(int m){
this.value+=m;
}
public synchronized void dec(int m){
this.value-=m;
}
}
引入可重入锁即可以在同一个线程内多次获取该锁
package com.ghc.test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private Lock lock = new ReentrantLock();
private int value;
public void inc(int m){
if(lock.tryLock()){
try{
this.value+=m;
}finally{
lock.unlock();
}
}
}
public void dec(int m){
if(lock.tryLock()){
try{
this.value-=m;
}finally {
lock.unlock();
}
}
}
public int getValue(){
lock.lock();
try{
return this.value;
}finally {
lock.unlock();
}
}
public static void main(String [] args) throws InterruptedException{
System.out.println(Thread.currentThread().getName()+" start...");
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" start...");
try{
Thread.sleep(1000);
}catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+" end...");
},"download thread").start();
Thread.sleep(500);
System.out.println(Thread.currentThread().getName()+" end...");
}
}
引入 可重入 读写锁,因为 可以同时读 , 不可同时写入 或者说不可同时读写
引入 可重入读写锁在同时写入的时候会加锁进行同步,而在同时读取的时候则不会提高并发性能
package com.ghc.test;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Counter {
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
private final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
private int value;
public void inc(int m){
// 写 锁
writeLock.lock();
try{
this.value+=m;
}finally {
writeLock.unlock();
}
}
public void dec(int m){
// 读锁
readLock.lock();
try{
this.value-=m;
}finally {
readLock.unlock();
}
}
}
写在最后