JAVA多线程的一点知识
来源:互联网 发布:dnf辅助端口免费制卡 编辑:程序博客网 时间:2024/05/24 04:47
线程与进程
一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
线程安全
经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果。
线程状态
线程Blocked状态
- 调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
- 调用wait(),使该线程处于等待池(wait blocked pool),直到notify()/notifyAll(),线程被唤醒被放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)
- 对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
- JAVA多线程的一点知识
- 学习一点java的知识
- Java内部类的一点知识
- 关于java中getContentPane()的一点知识
- 关于Java GUI的一点知识
- java ant知识的一点积累
- Java中的线程的一点知识
- Java中继承的一点小知识
- 关于JAVA多线程编程的一点笔记
- 关于java中多线程的一点理解
- 对java多线程的一点思考
- final 的一点知识
- vector的一点知识
- urllib2 的一点知识
- DB_DOMAIN的一点知识
- 一点php的知识
- urllib2 的一点知识
- 一点KeepAlive的知识
- 查询,修改 数据库
- SourceTree的基本使用
- 基础练习 杨辉三角形
- 特权同学的异步复位,同步处理方法总结
- linux 下获取当前时间精确到微妙
- JAVA多线程的一点知识
- 第六周周总结
- B/S和C/S的区别及应用
- jquery选择器
- OpenCV拷贝与ROI
- 卷积神经网络(Convolutional Neural Network)
- AndroidStudio(3.0.x版本)输入法无提示问题解决方案
- invalid mode 报错
- leetcode 698. Partition to K Equal Sum Subsets