JAVA多线程的一点知识

来源:互联网 发布:dnf辅助端口免费制卡 编辑:程序博客网 时间:2024/05/24 04:47

线程与进程

一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。

进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

线程安全

经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果。

线程状态

这里写图片描述

线程Blocked状态

  1. 调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
  2. 调用wait(),使该线程处于等待池(wait blocked pool),直到notify()/notifyAll(),线程被唤醒被放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)
  3. 对Running状态的线程加同步锁(Synchronized)使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。
    此外,在runnable状态的线程是处于被调度的线程,此时的调度顺序是不一定的。Thread类中的yield方法可以让一个running状态的线程转入runnable。

monitor

Monitor其实是一种同步工具,也可以说是一种同步机制,它通常被描述为一个对象,主要特点是:

  • 对象的所有方法都被“互斥”的执行。好比一个Monitor只有一个运行“许可”,任一个线程进入任何一个方法都需要获得这个“许可”,离开时把许可归还。
  • 通常提供singal机制:允许正持有“许可”的线程暂时放弃“许可”,等待某个谓词成真(条件变量),而条件成立后,当前进程可以“通知”正在等待这个条件变量的线程,让他可以重新去获得运行许可。

Monitor对象可以被多线程安全地访问。
每个Java对象都有一个内部锁“Instrinsic lock”。有了这个锁的帮助,只要把类的所有对象方法都用synchronized关键字修饰,并且所有域都为私有(也就是只能通过方法访问对象状态),就是一个Monitor了。
示例:

public class Account {    private int balance;    public Account(int balance) {        this.balance = balance;    }    synchronized public boolean withdraw(int amount){        if(balance<amount)            return false;        balance -= amount;        return true;    }    synchronized public void deposit(int amount){        balance +=amount;    }}

synchronized关键字

修饰方法

表示进入该方法需要对Instrinsic lock加锁,离开时放锁。

用在程序块中

对哪个对象的Instrinsic lock加锁。

示例:

synchronized public void deposit(int amount){    balance +=amount;}// 等价于public void deposit(int amount){    synchronized(this){        balance +=amount;    }}

基本线程类

基本线程类指的是Thread类,Runnable接口,Callable接口
Thread 类实现了Runnable接口,启动一个线程的方法:

MyThread my = new MyThread();my.start();

Thread类的相关方法

//当前线程可转让cpu控制权,让别的就绪状态线程运行(切换)public static Thread.yield() //暂停一段时间public static Thread.sleep()  //在一个线程中调用other.join(),将等待other执行完后才继续本线程。    public join()//后两个函数皆可以被打断public interrupte()

关于中断:它并不像stop方法那样会中断一个正在运行的线程。线程会不时地检测中断标识位,以判断线程是否应该被中断(中断标识值是否为true)。终端只会影响到wait状态、sleep状态和join状态。被打断的线程会抛出InterruptedException。
Thread.interrupted()检查当前线程是否发生中断,返回boolean
synchronized在获锁的过程中是不能被中断的。

中断是一个状态!interrupt()方法只是将这个状态置为true而已。所以说正常运行的程序不去检测状态,就不会终止,而wait等阻塞方法会去检查并抛出异常。如果在正常运行的程序中添加while(!Thread.interrupted()) ,则同样可以在中断后离开代码体.

Thread类最佳实践

写的时候最好要设置线程名称 Thread.name,并设置线程组 ThreadGroup,目的是方便管理。在出现问题的时候,打印线程栈 (jstack -pid) 一眼就可以看出是哪个线程出的问题,这个线程是干什么的。

如果获取线程中的异常

处理Java线程池中的异常消失

由于线程池自身的保护机制,不会将异常打印到控制台,所以有时程序莫名其妙的结束。下面代码加异常捕获:

    public  void start() {                  System.out.println("async TNonblockingServer start ....");            Runnable simple = new Runnable() {                public void run() {                    TProcessor tprocessor = new MessageForwardsService.Processor<MessageForwardsService.Iface>(new MessageForwardsRpcInterface());                    nonblocking(tprocessor);                }            };            Thread t = new Thread(simple);            t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {                  @Override                  public void uncaughtException(Thread t, Throwable e) {                      //可以捕获到                    System.out.println("uncaughtExceptionHandler catch a Exception---------");                      System.out.println(e.getMessage());                  }              });             t.start();    }

不能用try catch来获取线程中的异常。

Runaable

与Thread类似

Callable

future模式:并发模式的一种,可以有两种形式,即无阻塞和阻塞,分别是isDone和get。其中Future对象用来存放该线程的返回值以及状态

ExecutorService e = Executors.newFixedThreadPool(3); //submit方法有多重参数版本,及支持callable也能够支持runnable接口类型.Future future = e.submit(new myCallable());future.isDone() //return true,false 无阻塞future.get() // return 返回值,阻塞直到该线程运行结束

高级多线程控制类

可查看下面的参考文章原文。

1.ThreadLocal类

2.原子类(AtomicInteger、AtomicBoolean……)

3.Lock类 

4.容器类

5.管理类

参考文章:
https://www.cnblogs.com/wxd0108/p/5479442.html

原创粉丝点击