并发编程基础

1、线程简介

(1)线程是操作系统调度的最小单元;
(2)在一个进程里可以创建多个线程,这些线程都有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量;
(3)一个程序作为一个进程来运行,程序运行过程中可以创建多个线程;
(4)一个线程在一个时刻只能运行在一个处理器上,多线程程序可以充分利用多处理器执行任务;
(5)线程优先级:线程优先级决定线程需要多或者少分配处理器资源的线程属性;(有些操作系统会忽略对线程优先级的设定,使其无效);

2、线程的状态

在这里插入图片描述

3、新建一个线程的方式

(1)继承Thread,重写run方法
(2)实现Runnable,接口重写run方法

4、Daemon线程

Daemon线程是一种支持型线程,作为后台调度以及支持性工作,当java虚拟机中不存在非Deamon线程的时候,java虚拟机将会退出(即当只剩下Daemon线程的时候,jvm将退出,最终Daemon线程也将终止);Daemon线程可以通过thread.setDaemon(true) 实现

5、中断interrupt

线程中断是一种软性的停止线程的机制,(thread.interrupt())它并不会立即终止线程;而是通知被中断线程“希望”该线程尽快停止,否则可能造成在修改某个对象的时候被强制终止并释放锁,读线程会读到一个未完全初始化的该对象。(正确合理的终止一个线程应该采用interrupt()方法,而不是强制性使用stop())

6、volatile和synchronized关键字

(1)volatile
关键字volatile可以用来修饰成员变量,告诉程序任何对该变量的访问都要从共享内存中获取,并且对它的改变必须同步刷新回共享内存中,它保证了所有线程对该变量访问的可见性;任何对该变量的访问和修改都以共享内存为主(线程间通过共享内存的方式通信)

(2)synchronized
关键字synchronized可以修饰方法或者同步块的形式使用,主要确保多个线程在同一时刻,只能有一个线程处于方法或者同步块中,保证了线程对变量访问的可见性和排他性

7、等待通知机制

(1)使用wait()、notify()和notifyAll()时需要先对调用对象加锁
(2)notify()和notifyAll()方法调用后,等待线程依旧不会从wait()方法返回,需要调用notify()和notifyAll()的线程释放锁后,等待线程才有机会从wait()返回
(3)notify()方法将等待队列中的一个线程移到同步队列;notifyAll()方法将等待队列中的所有线程移到同步队列;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class WaitNotify {
    static boolean flag = true;
    static Object lock = new Object();

    public static void main(String[] args) throws Exception{
        Thread waitThread = new Thread(new Wait(),"WaitThread");
        waitThread.start();
        TimeUnit.SECONDS.sleep(1);
        Thread notifyThread = new Thread(new Notify(),"NotifyThread");
        notifyThread.start();
    }

    static class Wait implements Runnable {
        @Override
        public void run() {
            // 加锁,拥有lock的Monitor
            synchronized(lock) {
                // 当条件不满足时,继续wait,同时释放了lock的锁
                while(flag) {
                    try {
                        System.out.println(Thread.currentThread()+"flag is true. wait @ "+
                                new SimpleDateFormat("HH:mm:ss").format(new Date()));
                        lock.wait();
                    }catch (InterruptedException e) {

                    }
                }
                // 当条件满足时,完成工作
                System.out.println(Thread.currentThread()+"flag is false. running @ "+
                        new SimpleDateFormat("HH:mm:ss").format(new Date()));
            }
        }
    }

    static class Notify implements Runnable {
        @Override
        public void run() {
            // 加锁,拥有lock的Monitor
            synchronized(lock) {
                // 获得lock的锁,然后进行通知,通知时不会释放lock的锁,
                // 直到当前线程释放了lock后,WaitThread才能从wait方法中返回
                System.out.println(Thread.currentThread()+"hold lock. notify @ "+
                        new SimpleDateFormat("HH:mm:ss").format(new Date()));
                lock.notifyAll();
                flag = false;
                SleepUtils.second(5);
            }
            // 再次加锁
            synchronized (lock) {
                System.out.println(Thread.currentThread()+"hold lock. again. sleep @ "+
                        new SimpleDateFormat("HH:mm:ss").format(new Date()));
                SleepUtils.second(5);
            }
        }
    }

}

class SleepUtils {
    public static final void second(long seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        }catch (InterruptedException e) {

        }
    }
}
输出:
>>> Thread[WaitThread,5,main]flag is true. wait @ 23:23:29
>>> Thread[NotifyThread,5,main]hold lock. notify @ 23:23:30
>>> Thread[NotifyThread,5,main]hold lock. again. sleep @ 23:23:35
>>> Thread[WaitThread,5,main]flag is false. running @ 23:23:40
8、Thread.join()的使用

一个线程A执行了thread.join()语句(如果是主线程,则是main()中执行thread.join()语句,如果是子线程,则是run()中执行thread.join()语句),其含义是:当前线程A等待thread线程终止之后,才从thread.join()返回

9、yield()方法的使用

作用:暂停当前正在执行的线程对象。

yield()方法是停止当前线程,让同等优先权的线程或更高优先级的线程有执行的机会。如果没有的话,那么yield()方法将不会起作用,并且由可执行状态后马上又被执行。

10、wait()和sleep()方法的区别(有没释放锁)

sleep方法没有释放锁;
wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁)

参考

《Java并发编程的艺术》
https://www.cnblogs.com/loren-Yang/p/7538482.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值