Java并发


多线程创建

多线程创建有三种方式:

①继承Thread类

②实现Runnable接口

③实现Callable接口

其中Thread类其实也是一个实现了Runnable接口的类。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class test {
    public static void main(String args[]){
        new Mythread1().start();
        new Thread(new Mythread2()).start();

        FutureTask ft = new FutureTask(new Mythread3());
        new Thread(ft).start();
        try {
            Integer i = ft.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

class Mythread1 extends Thread{
    @Override
    public void run() {
        System.out.println(1);
    }
}

class Mythread2 implements Runnable{
    @Override
    public void run() {
        System.out.println(2);
    }
}

class Mythread3 implements Callable {
    @Override
    public Integer call() throws Exception {
        System.out.println(3);
        return 1;
    }
}

静态代理

真实对象和代理对象实现同一个接口。

代理对象代理真实角色。

下面这个栗子用Family代理Child

public class test {
    public static void main(String args[]) {
        Child child = new Child();
        Family family = new Family(child);
        family.goToSchool();
    }
}
interface Behave{
    void goToSchool();
}
//interface中的成员变量隐式指定为为public static final类型
//interface中的方法隐式指定为public abstract类型
class Child implements Behave{
    @Override
    public void goToSchool() {
        System.out.println("The child is sleeping");
    }
}

class Family implements Behave{
    private Behave target;
    Family(Behave target){
        this.target=target;
    }
    @Override
    public void goToSchool() {
        System.out.println("making breakfast");
        target.goToSchool();
        System.out.println("driving to school");
    }
}

Lambda

任何接口,如果只包含唯一一个抽象方法,那么他就是一个函数式接口。

对于函数式接口,可利用Lambda表达式创建该接口的一个对象。

下面这个栗子中等号右边其实就是一个实现了Behave这个接口的一个实现类所创造的对象。

Behave behave = ()-> System.out.println(1);

 线程方法

①setPriority

②sleep 毫秒 1000ms=1s

③join 强制执行,堵塞其他线程,直到自己执行完成

④yield 礼让

线程中止

使用一个标志位作为终止变量,从外部传入flag=false中止该线程

线程同步

每个对象对应一把锁

public class test{
int count;
public
synchronized void method{
...
}
}

锁的是自己所在的这个对象

同步块

synchronized(对象名){
... }

可以锁另一个对象

ReentrantLock 可重入锁

private final ReentrantLock lock = new ReentrantLock();
public void method(){
    lock.lock();
     ...
    lock.unlock();
}

管程法与信号灯法

wait 等待,即缓冲区满后等待,堵塞线程,与锁无关

notify 唤醒

操作共享变量首先加锁 synchronized,而后通信 wait,notify

信号灯法,设立一个标志位(告诉线程什么时候等待,什么时候唤醒),即缓冲区为1的管程法。

线程池

不频繁创建和销毁线程,降低资源消耗

Executors 工具类,线程池的工厂类,用于创建并返回不同类型的线程池

下面这个栗子是实现runnable接口的线程,无返回值。

ExecutorService ser = Executors.newFixedThreadPool(10);
ser.execute(new Thread(()-> System.out.println(1)));
ser.execute(new Thread(()-> System.out.println(2)));
ser.shutdown();

下面这个栗子是实现callable接口的线程,有返回值。

ExecutorService ser = Executors.newFixedThreadPool(10);
Future future = ser.submit(t); //t是一个实现了callable接口的对象,返回值为Integer型
Integer result = future.get();
ser.shutdown();