1.程序、进程、线程
程序program是一段静态的可执行的指令
进程process是正在运行的一个程序
线程thread是进程内部的执行路径
每条线程具有独立的运行栈和程序计数器(PC)
一个进程中的多条线程共享同一片内存空间(方法区和堆)
并行 多个cpu同时执行多个任务
并发 一个cpu"同时"执行多个任务
2.Thread类创建多线程
方式一:继承Thread类
继承Thread类的子类,重写run()方法,创建子类对象调用start()方法
start()-->1启动当前线程 2调用当前线程的run()方法
子类对象.run()仅仅是调用方法,仍在主线程main之中
方式二:Thread的匿名子类对象
new Thread(){
@Override
public void run(){
//重写的方法体
}
}.start();
3.方法
Thread.currentThread() //获取当前线程对象
setName()
getName()
yield() //调用该方法的线程对象放弃当前拥有的cup资源
join() //在线程a中调用线程b.join(),线程a进入阻塞状态,等线程b完全执行完毕之后,线程a才结束阻塞状态
stop() //过时,强制结束线程生命周期
sleep(long millitime) //当前线程“睡眠”指定的毫秒数
isAlive() //判断当前线程是否存活
4.线程的优先级
高优先级的线程抢占cpu资源的概率更高
MAX_PRIORITY 10
MIN_PRIORITY 1
NORM_PRIORITY 5 默认
getPriority()
setPriority()
5.Runnable接口创建多线程
步骤
1 创建实现Runnable接口的类
2 实现Runnable接口的run()方法
3 创建接口实现类的对象p
4 new Thread(p).start()
匿名实现
new Thread(new Runnable(){
@Override
public void run(){
//实现run方法
}
}).start();
Runnable的优势
打破单继承的局限性,不必继承Thread类
更适合处理多个线程具有共享数据的情况
6.线程的同步
方式一:同步代码块
//同步监视器,俗称“锁”,可放任何类的对象
//但是要求操作共享数据的多个线程使用同一把锁
//使用继承Thread类实现的话,可以用static的对象或当前类.class作为锁
//使用Runnable接口实现,锁可以用this当前对象
synchronized(同步监视器) {
//需要被同步的代码(操作共享数据的代码)
}
方式二:同步方法
不需要显式声明同步监视器
//非静态的同步方法的同步监视器是this
//静态的同步方法的同步监视器是 当前类.class
7.线程安全的单例模式
懒汉式单例模式复习
class Bank{
private Bank(){} //私有化构造器,只能在类内部创建对象
private static Bank bank = null; //静态
public static Bank getBankInstance(){
if(bank == null){
bank = new Bank();
}
return bank;
}
}
线程安全的懒汉式单例模式
方式一:效率稍差
synchronized(Bank.class){
if(bank == null){
bank = new Bank();
}
}
return bank;
方式二:
if(bank == null){
synchronized(Bank.class){
if(bank == null){
bank = new Bank();
}
}
}
return bank;
8.死锁
不同线程分别占据对方需要的同步资源,都等待对方放弃资源
程序不会抛异常,也不会停止执行,僵住了,应尽量避免这种情况
9.Lock接口
ReentrantLock lock = new ReentrantLock();
try{
lock.lock(); //手动开启同步锁
//同步代码
}finally{
lock.unlock(); //手动解除同步锁
}
synchronized 与 Lock 的异同?
同:都用来解决线程安全问题
异: synchronized 执行完代码后,自动释放同步监视器
Lock 手动开启同步(lock),手动结束同步(unlock)
10.线程的通信
wait() //阻塞当前线程
notify() //唤醒被wait的一个线程,优先级高的先被唤醒
notifyAll() //唤醒所有wait的线程
注意
1.这三个方法只能出现在同步代码块或同步方法中
2.这三个方法的调用者必须是同步代码块或同步方法中的同步监视器,否则出现IllegalMonitorStateException
3.这三个方法定义在java.lang.Object中
sleep() 和 wait() 的异同?
同:都使当前线程进入阻塞状态
异: 1)Thread类中定义静态方法sleep(),objcet类中定义wait()
2)sleep()在任何需要的场景下调用,wait()必须使用在同步代码块或同步方法中
3)sleep()不会,wait()会释放锁
11.JDK5.0新增线程创建方式
方式一: 实现Callable接口
实现call()方法,可以有返回值,可以抛异常
Future接口
可以对Callable、Runnable任务的执行结果进行取消、查询是否完成、获取结果等
FutureTask类是Future接口的唯一实现类,其实现了Runnable、Future接口
FutureTask类可以作为Runnable被线程执行,也可以作为Future获取Callable的返回值
eg:
FutureTask futureTask = new FutureTask(new Callable(){
@Override
public Object call() throws Exception {
return 3;
}
});
new Thread(futureTask).start();
try {
Object o = futureTask.get();
System.out.println(o);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
方式二:使用线程池
ExecutorService接口
Executors工具类
eg:
ExecutorService service = Executors.newFixedThreadPool(10); //创建固定数量的线程池
System.out.println(service.getClass()); //class java.util.concurrent.ThreadPoolExecutor 可以管理线程池的一些属性
service.execute(new Runnable() {
@Override
public void run() {
//重写run()方法
}
});
service.submit(new Callable() {
@Override
public Object call() throws Exception {
return null;
}
});
service.shutdown(); //关闭连接池
标签:同步,java,Thread,012,Runnable,线程,new,bank
From: https://www.cnblogs.com/zhengcg/p/16601903.html