《Java并发编程的艺术》并发编程的基础(四)

一、线程简介

1.线程的概念

系统运行的最小单元

2.为何使用多线程

更好地利用系统资源(处理器多核心),提高响应速度。

3.线程的状态

NEW(创建状态)

RUNABLE(运行状态,系统调度,争抢时间片)

BLOCKED(阻塞状态,加了锁,其它线程获得到了锁)

WATING(等待状态,wait()方法时,使用notify()唤醒)

TIMED_WAITING(超时等待状态,线程sleep()时,) 

TERMINAL(线程终止)

关于wait和notify:

public class ThreadTest {

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Waiting(), "WaitingThread");
        Thread thread2 = new Thread(new NotifyWaiting(), "NotifyWaitingThread");

        thread.start();

        TimeUnit.SECONDS.sleep(2);

        thread2.start();
    }
}

class Waiting implements Runnable {

    @Override
    public void run() {
        synchronized (Waiting.class) {
            try {
                System.out.println("Current thread: " + Thread.currentThread().getName() + ",Waiting is waiting!");
                Waiting.class.wait();
                System.out.println("Current thread: " + Thread.currentThread().getName() + ",Waiting is notified!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class NotifyWaiting implements Runnable {

    @Override
    public void run() {
        synchronized (Waiting.class) {
            Waiting.class.notify();
            System.out.println("Current thread: " + Thread.currentThread().getName() + ",Waiting is notified!");
        }
    }
}

结果:

Current thread: WaitingThread,Waiting is waiting!
Current thread: NotifyWaitingThread,Waiting is notified!
Current thread: WaitingThread,Waiting is notified!

wait方法会释放锁,sleep则不会

二、启动和终止线程

1.启动线程

1.构建线程

new Thread();

new Runable();

new Callable(); //Callable可以返回Future携带返回值

注意:最好给线程初始化名称,方便JVM分析。

2.启动线程

thread.start();

或者Excutors.new线程池,然后ExecutorService.submit或者excute

2.终止线程

终止线程最好使用一个volatile修饰的boolean开关去进行控制

三、线程之间的通信

1.volatile与synchronized关键字

多个线程共享一个变量的话,会在线程里有一个变量的拷贝,提升运行效率,而导致线程不安全,而 volatile 关键字让变量直接从共享内存中读写,保证变量的安全性,但是效率却降低了。

2.wait()与notify()

 wait() 方法与锁对象一起使用,调用wait()方法会释放所对象。 

wait()标准范式:

synchronized(对象A){
    while(条件不成立) {
        对象A.wait();
    }
doSomething(); }

notify()标准范式:

synchronized(对象A){
改变条件; 对象A.notify(); }

解读:

(1)wait()方法块,获取锁对象A;

(2)wait()方法块,锁对象A调用wait()方法,释放锁,进入WAIT状态,方法块进入WAIT队列;

(3)notify()方法块,获取所对象A;

(4)notify()方法块,改变条件,wait()方法块处于WAIT状态;

(5)notify()方法块,对象A调用notify()方法,此时wait()方法块离开WAIT队列,进入对象A的阻塞队列中;

(6)notify()方法块释放锁,wait()方法块获得锁,继续执行方法块,doSomething();

3.Thread.join()

在线程A中执行线程B.join():要先执行完线程B终止之后才从线程B.join()返回。

四、线程应用实例

1.等待超时模式

伪代码:

public synchronized Object get(long mills) throws InterruptedException {
    long future = System.currentTimeMillis() + mills;
    long remaining = mills;

    while(result == null && remaining > 0) {
        wait(mills);
        remaining = future - System.currentTimeMillis();
    }

    return result;
}

解读:在超时mills毫秒之后,返回结果;

2.适用

连接池(连接池超时),线程池(线程池等待超时)


原文地址:https://www.cnblogs.com/lcmlyj/p/11008311.html