Java高并发程序设计(二)Java并行程序基础

标签: 多线程  并发  Java

1.什么是线程

线程是进程内的执行单元。一个进程内可以有多个线程同时在执行。
线程的状态:新建(NEW),可运行(RUNNABLE),运行(RUNNING),阻塞(BLOCKED),死亡(DEAD)

1.1新建(NEW):新创建了一个线程对象。

1.2 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

1.3 运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
1.4 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种: 

(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

1.5 死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

新建一个线程: 

方法一,创建Thread,覆写run()方法

Thread t1=new Thread(){
    @Override
    public void run(){
        System.out.println("Hello, I am t1");
    }
};
t1.start();

方法二,实现Runnable接口

public static class MyTask implements Runnable {
    @Override
    public void run() {
        System.out.println("Hello, I am task1");
    }
}

Thread t2 = new Thread(new MyTask());
t2.start();

2.线程的基本操作

public void Thread.interrupt() // 中断线程
public boolean Thread.isInterrupted() // 判断是否被中断
public static boolean Thread.interrupted() // 判断是否被中断,并清除当前中断状态
public static native void sleep(long millis) throws InterruptedException //线程进入休眠指定时间

suspend():挂起,不会释放锁;

resume():继续执行线程;
join():等待线程结束;

yeild():谦让

不要在Thread实例上使用 wait()和notify()方法
notifyAll():唤醒所有等待的线程,让它们继续竞争锁

3.守护线程

在后台默默地完成一些系统性的服务,比如垃圾回收线程、 JIT线程就可以理解为守护线程
当一个Java应用内,只有守护线程时,Java虚拟机就会自然退出

Thread t3 = new Thread();
t3.setDaemon(true);
t3.start();

4.线程优先级

public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
高优先级的线程更容易再竞争中获胜
 

//线程优先级设置
Thread high= new Thread();
Thread low= new Thread();
high.setPriority(Thread.MAX_PRIORITY);
high.start();
low.setPriority(Thread.MIN_PRIORITY);
low.start();

5.基本的线程同步操作

synchronized
– 指定加锁对象:对给定对象加锁,进入同步代码前要获得给定对象的锁。
– 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。
– 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。
Object.wait() :会释放锁。

Obejct.notify():随机唤醒一个线程。

Obejct.notifyAll():会唤醒全部线程。

//指定加锁对象
public void run() {
    for(int j=0;j<10000000;j++){
        synchronized(instance){
            i++;
        }
    }
}

//用在方法上
public synchronized void increase(){
    i++;
}

/**
 * 线程阻塞与唤醒
 * Created by chenbin on 2019\8\25 0025.
 */
public class SyncThread {
    private static final Object object = new Object();

    //t1线程执行,被object.wait()阻塞
    static class T1 extends Thread{
        public void run(){
            synchronized (object) {
                System.out.println(System.currentTimeMillis()+":T1 start! ");
                try {
                    System.out.println(System.currentTimeMillis()
                            +":T1 wait for object ");
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis()+":T1 end!");
            }
        }
    }

    //t2线程执行,object.notify()唤醒t1线程
    static  class T2 extends Thread {
        public void run() {
            synchronized (object) {
                System.out.println(System.currentTimeMillis()
                        + ":T2 start! notify one thread");
                object.notify();
                System.out.println(System.currentTimeMillis() + ":T2 end!");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                }
            }
        }
    }

    public static void main(String[] args) {
        T1 t1 = new T1();
        T2 t2 = new T2();

        t1.start();
        t2.start();
    }
}

程序main函数执行输出如下:

源代码可以在github上下载:https://github.com/chenbin911029/mutiThread 

本文中的两个class文件是:com.thread.simple包下面的SimpleThread,SyncThread

备注:本文为JAVA高并发程序设计(葛一鸣著)读书笔记,以及自身的整理和实践。

版权声明:本文为chenbin1991smile原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chenbin1991smile/article/details/100065280