1. 基本概念
- 一个java应用程序java.exe至少有三个线程:main()主线程,gc()垃圾回收线程,异常处理线程
- 并行:多CPU多任务
2.线程的创建和使用
- 方式一:继承于thread类
1.创建一个继承于thread的子类
2.重写run方法 —>此线程执行的操作
3.创建子类对象
4.对象调用start
class MyThread extends Thread{ public void run(){ Syso(); } } public class ThreadTest(){ Public static void main(String[] args){ MyThread t1 = new MyThread(); t1.start(); } }
创建Thread匿名子类的方式
new Thread(){ /// }.run();
- 方式二:实现Runnable接口
1.创建实现Runnable接口的类
2.实现抽象方法run()
3.创建对象
4.将对象传至Thread类的构造器,创建Thread对象
5.通过Thread对象调用start
class MThread implements Runnable{ Public void run(){} } public class ThreadTest{ Public static void mian(){ MThread mThread = new MThread(); Thread t1 = new Thread(mThread); t1.start(); } }
- Thread类常用方法
1.start
2.run
3.currentThread返回执行当前代码线程
4.getName获取线程名字
5.setName设置线程名
6.yield释放当前线程执行权
7.t1.join t1 执行
8.stop() 已过时,强制结束当前线程
9.sleep(long millitime) 线程睡眠指定毫秒数
10.isAlive()。判断线程是否还存活
- 线程优先级
1.MAX = 10,MIN = 1 , NORM = 5
2.getPriority()
3.setPriority()
3.线程的生命周期
- NEW,RUNNABLE,BLOCKED,WAITTING,TIMED_WAITTING,TERMINATED
- 新建,就绪,运行,阻塞,死亡
-
4.线程同步
方式一:同步代码块
synchronized(同步监视器){
//需要被同步的代码
} 操作共享数据的代码即需要被同步的代码 方式一创建的线程:锁可用this,因为创建时使用的是同一个对象 方式二创建的线程:可以用类名.class,因为类也是对象,而且类只会加载一次
同步监视器,俗称锁
任何一个类的对象都可以充当锁
多个线程必须使用同一把锁同步方法
解决实现 private synchronized void show(){
//方法体,操作共享变量的方法 }解决继承:静态方法

非静态同步方法,同步监视器是this
静态同步方法,同步监视器是类本身
- 使用同步方法使懒汉式线程安全
方式一:效率差
方式二:效率稍高
- 线程死锁
解决线程安全问题的方式三 Lock锁:
Lock接口的实现类ReentrantLock构造同步锁
1.实例化ReentrantLock 2.调用lock方法 3.finally 调用unlock解锁


面试题:synchronized与lock的异同点:
相同:都可以解决线程安全问题
不同:synchronized在执行完相应的同步代码之后,会自动的释放同步监视器。
lock需要手动的启动与结束同步。
优先使用顺序:lock-》同步代码块-》同步方法
5.线程通信
- 线程通信的例子:使用两个线程交替打印1-100

涉及到的三个方法:
wait():阻塞线程,同时会释放锁
notify():唤醒优先级最高的线程
notifyAll():唤醒所有wait的线程
此三个方法都必须使用在同步代码快中
- 面试题:sleep和wait的异同
1.相同:都可进入阻塞
2.不同:1.声明位置不同sleep:thread
wait:Objtct
2.调用要求不同。sleep可在任何需要下,wait必须在同步代码块
3.sleep不释放同步监视器,wait释放同步监视
生产者消费者模型练习p443
6.jdk5.0新增线程创建方式
- 新增方式一:实现Callable接口,比实现Runnable接口更强大。
有返回值,可以抛出异常,支持泛型,
1.创建实现callable接口的类 2.实现call方法 3.创建Callable接口实现类的对象 4.将Callable接口对象传递到FutureTask构造器中,创建futureTask类 5.将futureTask对象作为对象传递到Thread类构造器中,创建Thread对象,调用start(); 6.获取Callable中call方法的返回值。+ class NumThread implements Callable{ public Object call() throws Exception{
} } public class ThreadNew{ Psvm(){
NumThread numThread = new NumThread(); new Thread(numThread).start(); FutureTask futureTask = new FutureTask(numThread);Object value = futureTask.get(); } }
- 创建线程的方式4:使用线程池
相关API:ExecutorService和Executors
ExecutorService:真正的线程池API Executors:线程池工厂类 //1.提供线程池 ExecutorService service = Executors.newFixedThreadPool(10); //2.指定线程要做的事
service.submit(new NumberThread1());//适合于使用callable service.execute(new NumberThread());//适合于使用runnable service.shutdown();//关闭线程池
