线程学习笔记(上)
目录:
- 程序 进程 线程
- Java实现多线程
- 线程的状态和方法
- 线程基本信息和优先级
- 线程的同步和死锁问题
- 生产者消费模式
- 任务调度
线程的概念
程序 进程 线程
- 程序(Program):指令集 静态概念
- 进程(Process):操作系统 调度程序 动态概念
- 线程(Thread):在进程内多条执行路径
线程是进程中的一个“单一的连续控制流程”/执行路径
- 线程又被成为轻量级进程
- Thread run at the same time,independently of one another
- 一个进程可拥有多个并行的线程
- 一个进程中的线程共享相同的内存单元/内存地址空间->可以访问相同的变量和对象,而且它们从同一堆中分配对象->通信、数据交换、同步操作(所以线程容易产生并发问题)
- 由于线程间的通信在同一地址空间上进行的,所以不需要额外的通信机制,这就使得通信更简便而且信息传递的速度也更快
线程的实现
继承Thread+run()
启动:创建子类对象+对象.start()
步骤:
- 创建多线程 继承Thread +重写run(线程体)
- 使用线程,创建子类对象 + 对象.start() 线程启动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public class Rabbit extends Thread { @Override public void run() { for(int i=0;i<100;i++){ System.out.println("兔子跑了"+i+"步"); } }
public static void main(String[] args){ Rabbit rabbit = new Rabbit(); Tortoise tortoise = new Tortoise();
rabbit.start(); tortoise.start();
for(int i=0;i<1000;i++){ System.out.println("main==>"+i); } } } class Tortoise extends Thread{ @Override public void run() { for(int i=0;i<100;i++){ System.out.println("乌龟跑了"+i+"步"); } } }
|
- 在Java中负责线程功能的是Java.lang.Thread类
- 可以通过创建Thread的实例来创建新的线程
- 每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作,方法run()称为线程体
- 通过调用Thread类的start()方法来启动一个线程
实现Runnable+run() (推荐)
此处用到了一个静态代理的原理。
静态代理模式,简而言之就是有一个真实角色,一个代理角色,且二者实现相同的接口,而代理角色则是持有真实角色的引用。
启动:使用静态代理
步骤:
- 创建真实角色
- 创建代理角色 Thread+引用
- 代理角色.start()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
public class Programmer implements Runnable { @Override public void run() { for(int i=0;i<1000;i++){ System.out.println("一边敲代码。。。"); } } public static void main(String[] args){ Programmer programmer = new Programmer(); Thread proxy = new Thread(programmer); proxy.start();
for(int i=0;i<1000;i++){ System.out.println("一边看小说..."); } } }
|
- 继承Thread类方式的缺点:如果我们的类已经从一个类继承,则无法继承Thread类
- 通过Runnable接口实现多线程
- 优点:可以同时实现继承。实现Runnable接口方式要通用一些(避免单继承的局限性;便于共享资源,同一份资源,多个代理访问)
通过Callable接口实现多线程 (了解)
步骤:
- 创建Callable实现类+重写call
- 借助 执行调度服务ExecutorService,获取Future对象
- 获取值result.get()
- 停止服务set.shutdownNow()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
public class Call { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService ser = Executors.newFixedThreadPool(2); Race tortoise = new Race("乌龟",150); Race rabbit = new Race("兔子",50); Future<Integer> result1 = ser.submit(tortoise); Future<Integer> result2 = ser.submit(rabbit);
Thread.sleep(1000); tortoise.setFlag(false); rabbit.setFlag(false);
int num1 = result1.get(); int num2 = result2.get(); System.out.println("乌龟跑了-->"+num1+"步"); System.out.println("兔子跑了-->"+num2+"步"); ser.shutdownNow(); }
} class Race implements Callable<Integer>{ private String name; private long time; private boolean flag = true; private int step = 0; public Race(){}
public Race(String name,long time){ super(); this.name = name; this.time = time; }
public void setFlag(boolean flag) { this.flag = flag; }
@Override public Integer call() throws Exception { while(flag){ Thread.sleep(time); step++; } return step; }
}
|