class Life{ public static void main(String[] args){ int alive; while(alive) { eat(); sleep(); code(); repeat(); } } }
老人说,这不丢脸,也无损真正的骄傲.
关于多线程的概念方面的某些东西,网上不同的人有不同的见解,也就不参加讨论了,比如线程的生命周期。我实在是太菜了,不敢妄下结论,所以就当记笔记一样了。多线程对于我而言,还是挺难的,写了很多代码,才把简单的一些东西闹懂。尽管简单的Demo会写,可还是不会运用到平时做的一些程序里面。
Java 多线程编程
进程/线程、并发/并行概念(内功,包括了线程状态,这里不写线程状态)
- 进程:正在进行中的程序。其实进程就是一个应用程序运行时的内存分配空间。
- 线程:是进程中一个程序执行控制单元,一条执行路径。(一个进程至少两个线程(主线程,GC))
- 并发:指两个或者多个事件在同一时间段发生(宏观上是同时,微观上仍是顺序执行)
- 并行:指两个或者多个事件在同一时刻发生
创建线程的两种方式
- 通过实现Runnable接口(借助Thread来运行线程)
- 通过继承Thread类本身
创建线程的两种方式的区别和联系
- 区别:Runnable可实现数据共享
- 联系:都借助Thread类来运行线程(因Runnable没有start()方法)
杂乱无章的知识点
- 返回当前线程的名称:Thread.currentThread().getName()
- 线程的名称是由:Thread-编号定义的。编号从 0 开始。
- 线程要运行的代码都统一存放在了 run 方法中。
- 线程要运行必须要通过类中指定的方法开启。start 方法。(启动后,就多了一条执行路径)
- 线程随机性的原理:因为 cpu 的快速切换造成,哪个线程获取到了 cpu 的执行权,哪个线程就执行。
- 实现 Runnable 接口可以避免单继承的局限性(所以推荐使用实现来创建线程)。
//有趣的面试题(学习资料上Copy)
new Thread(new Runnable(){ //匿名
public void run(){
System.out.println("runnable run");
}
})
{
public void run(){
System.out.println("subthread run");
}
}.start(); //结果:subthread run
多线程安全问题
涉及到的两个因素:1.共享数据 2.多步操作
解决安全问题的原理:只要将操作共享数据的语句在某一时段让一个线程执行完,在执行过程中,其他线程不能进来执行就可以解决这个问题(同步)。
三种解决方式:
同步代码块
//相对降低性能,因为判断锁需要消耗资源,产生了死锁 //多个线程必须保证使用的是同一个锁 synchronized(对象) { // 任意对象都可以。这个对象就是锁。 需要被同步的代码; }
同步函数:将同步关键字(synchronized)定义在函数上,让函数具备了同步性。
- 同步函数的锁是this
- 静态同步函数的锁是this的字节码文件(this.getClass())
Lock接口(1.5新特性):同步是隐示的锁操作,而 Lock 对象是显示的锁操作,它的出现就替代了同步。
//基本语法 lock.lock(); //获取锁 try { //TODO }finally{ lock.unlock(); //必须释放锁 }
线程通信:不是传输数据,而是控制线程状态
- wait(Lock:await):将同步中的线程处于冻结状态。释放执行权,释放锁。同时将线程对
象存储到线程池中。 notify(Lock:signal):唤醒线程池中某一个等待线程。
notifyAll(Lock:signalAll):唤醒的是线程池中的所有线程。
sleep:释放执行权,但不是不释放锁
- interrupt():中断线程。
- setPriority(int newPriority):更改线程的优先级。
- getPriority():返回线程的优先级。
- yield():暂停当前正在执行的线程对象,并执行其他线程。
- setDaemon(true):将该线程标记为守护线程或用户线程。
- join:临时加入一个线程的时候可以使用 join 方法。
//生产者与消费者实例(实现Runnable方式)
//生产者
class Producer implements Runnable{
Production p = null;
private boolean bool = true;
public Producer(Production p){
this.p = p;
}
public void run(){
while(true){
if(bool){
p.push("炸鸡");
bool = false;
}else{
p.push("啤酒");
bool = true;
}
}
}
}
//消费者
class Saler implements Runnable {
Production p = null;
public Saler(Production p){
this.p = p;
}
public void run(){
while(true){
p.popup();
}
}
}
//产品
class Production {
private boolean flag; //是否有了炸鸡、啤酒
private String name;
public synchronized void push(String name){
if(!flag){
this.name = name;
System.out.println("已生产:"+name);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = true;
this.notifyAll();
}else{
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public synchronized void popup(){
if(flag){
System.out.println("已消费:"+this.name+"....");
flag = false;
this.notifyAll();
}else{
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//测试类
public class Test {
public static void main(String[] args) {
Production p = new Production();
new Thread(new Producer(p)).start();
new Thread(new Saler(p)).start();
}
}
CNcots CN Caprice of the stone的简写, 译为石头的随想曲.
博客中有网上摘抄的资料. 有个人的一些小心得 ,有什么不对的地方, 还请各位观客老爷们指出.
JavaNote系列博客, 纯属个人学习时间段整理的一些笔记, 会坚持每周至少一更,多多关照.