线程
一.什么线程
**进程**:一个活动的应用程序就是一个进程(动态概念,静态指磁盘上的文件).多进程开发,多任务开发对硬件要求比较高,有人对进程进行缩小化,被称之为小进程
**线程**:是进程中真正执行任务的最小单元.一个进程可以有n个线程,这n个线程可以共享这个进程的资源.
二.线程执行过程(参考链接我是一个线程)
问题:
1.黑屋子是神马:线程池
2.处理完包裹后如何调回到黑屋子:只有线程池的线程在任务完成后会重新回到线程池,其他线程执行完成后就被销毁
3.计数器,用于记录当前执行到哪里,当重新获取CPU事件从上次结束的地方开始继续执行
4.经历的房间:
4.1 黑屋子
4.2 就绪大厅
4.3 工厂
4.4 休息大厅
5.垃圾回收器
6.如果一个应用有多个线程,那么这些线程间是如何调试
三.线程状态
new->新建状态
start->就绪状态->有了内存没有cpu
run->运行状态
bolck->阻塞状态->IO阻塞,访问数据等
->进入就绪状态
->运行状态
death->死亡状态
四.创建线程使用
Thread:
Runnable:
Callable:
public class ThreadDemo {
public static void main(String[] args) {
//1.定义一个线程
Thread thread=new Thread(){
//2.重写run方法
//run方法时线程真正执行任务的地方,当run方法执行完成,线程生命周期完成
@Override
public void run() {
super.run();
for (int i = 0; i < 100; i++) {
Calendar calendar=Calendar.getInstance(Locale.CHINESE);
System.out.println(calendar.get(Calendar.HOUR)+"小时");
System.out.println(calendar.get(Calendar.MINUTE)+"分钟");
System.out.println(calendar.get(Calendar.SECOND)+"秒");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread.start();
//接口对象不是线程对象,不可以直接使用start方法必须把Runnable接口
Thread thread1=new Thread(new Runnable() {
int i=0;
@Override
public void run() {
while (i++<10){
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread1.start();
//C#中的线程是可以有返回值和抛出异常的,Java为了拥有这种功能提出第三种方式
Callable<String> callable=new Callable<String>() {
//类似于Thread中的run方法
@Override
public String call() throws Exception {
Thread.sleep(100);
return "nohello";
}
};
//--FutureTask实现了Runnable和Future.既可以做为Runnable被Thread执行
//也可以作为Future获取Callable的结果
FutureTask<String> futureTask=new FutureTask<String>(callable);
new Thread(futureTask).start();
try {
System.out.println(futureTask.get());//get方法时阻塞的即只要没有获取结果程序执行会暂停
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
五.线程锁(同步锁概述)
前提练习:* 不用锁的情况下有三只猴子在分100个桃子,每个猴子分掉剩余桃子的一半,到分完为止
A:50
B:25
C:12.5//12
13
package com.howell.bean;
/**
* 猴子类
* Created by HowellZhang on 2016/8/16.
*/
public class Monkey implements Runnable{
private String name;
static int peachNumber=100;
int getNumber;
boolean flag=true;
public Monkey(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void run() {
while (flag) {
if (peachNumber==0){
flag=false;
System.out.println("桃子已分完");
}else if (peachNumber==1){
flag=false;
getNumber=1;
peachNumber=0;
}
getPeach();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void getPeach(){
if (peachNumber<=0){
System.out.println("没桃子了");
return;
}
getNumber=peachNumber/2;
peachNumber-=getNumber;
//获取当前线程名称
System.out.println(Thread.currentThread().getName()+"取桃子"+getNumber);
System.out.println(Thread.currentThread().getName()+"剩余桃子"+peachNumber);
}
}
package com.howell.main;
import com.howell.bean.Monkey;
/**
* Created by HowellZhang on 2016/8/16.
*/
public class MonkeyRun {
public static void main(String[] args) {
Monkey monkey=new Monkey("A");
Thread thread=new Thread(monkey);
thread.setName("monkey1");
thread.start();
Thread thread1=new Thread(monkey);
thread1.setName("monkey2");
thread1.start();
Thread thread2=new Thread(monkey);
thread2.setName("monkey3");
thread2.start();
}
}
线程锁常用2种形式:
1.synchronized
1.1锁对象 大家常用的对象
1.2锁方法
2.lock
package com.howell.main;
/**
* 锁对象
* Created by HowellZhang on 2016/8/16.
*/
class Runnable_demo implements Runnable {
private int ticket=10;
public Runnable_demo(){
}
@Override
public void run() {
for(int i=0;i<20;i++){
synchronized (this) {
if (this.ticket > 0) {
//休眠1s秒中,为了使效果更明显,否则可能出不了效果
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "号窗口卖出:" + this.ticket-- + "号票");
}
}
}
}
public static void main(String args[]){
Runnable_demo demo=new Runnable_demo();
//基于火车票创建三个窗口
new Thread(demo,"a").start();
new Thread(demo,"b").start();
new Thread(demo,"c").start();
}
}
package com.howell.main;
/**
* 锁方法
* Created by HowellZhang on 2016/8/16.
*/
class Runnable_demo implements Runnable {
private int ticket=10;
public Runnable_demo(){
}
@Override
public void run() {
for(int i=0;i<20;i++){
if (this.ticket > 0) {
//休眠1s秒中,为了使效果更明显,否则可能出不了效果
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
this.scale();
}
}
}
private synchronized void scale() {
if (this.ticket>0)
System.out.println(Thread.currentThread().getName() + "号窗口卖出:" + this.ticket-- + "号票");
}
public static void main(String args[]){
Runnable_demo demo=new Runnable_demo();
//基于火车票创建三个窗口
new Thread(demo,"a").start();
new Thread(demo,"b").start();
new Thread(demo,"c").start();
}
}