Java 线程
程序:静态代码 安装到硬盘上
进程:运行中的程序 是操作系统分配资源的最小单位
线程:线程是进程(程序)中最小执行单元,是CPU进行调度的最小单位
一个进程中可以包含多个线程,线程不能脱离进程而存在
一个线程只能属于一个进程
例:运行中的 Q Q 进程
主线程 负责启动程序 例如:Java中的main 启动Java主线程
一个聊天窗口就是一个线程,可以独立运行
一个进程内的所有线程共享同一个进程的内存资源
单校CPU 1个时间节点上只能处理1个任务 快 切换执行多个任务
//Thread类 用于创建线程,操作线程的类 创建线程方式:继承Thread类
public class ThreadDemo extends Thread{
//Java中要在线程中执行的任务,写在run()
@Override
public void run(){
for(int i=0;i<1000;i++){
System.out.println("Thread"+i);
}
}
}
public class Test {
//main 启动Java程序的主线程
public static void main(String[] args) {
//在主线程中创建线程,并启动线程
ThreadDemo td=new ThreadDemo ( );
//td.run();//切记不要调用run方法启动线程,这只是一个普通的方法调用,不是启动线程
td.start ();//启动线程 start0(); private native void start0(); 告诉操作系统开启线程,调度
for(int i=0;i<1000; i++){
System.out.println ("main"+i );
}
}
}
//让类实现Runnable接口,线程要执行的任务
public class MyThread implements Runnable{
@Override
public void run() {
for(int i=0;i<1000;i++){
System.out.println ("自定义线程任务"+i );
}
}
}
public class Test{
public static void main(String[] args) {
//创建了一个线程要执行的任务
MyThread myth=new MyThread ();
Thread th1=new Thread ( myth );//创建了一个线程,并为其分配了一个任务
th1.start ();
for(int i=0;i<1000;i++){
System.out.println ("main:"+i );
}
}
}
Thread类中的方法:
run(); 用于执行任务
start(); 启动线程
Thread.currentThread() //获得当前线程的引用
Thread.currentThread().getName()
getName() //获得线程的名字
Thread(myth,"窗口!"); // 构造方法,分配任务,定义线程名称
setName(String name); //定义线程名称
setPriority(); //Java中的线程支持设置优先级的,默认优先线是5,最低是1,最高是10
getPriority();
Java的调度方法:同优先级线程组成先进先出队列,使用时间片策略
对于高优先级,使用优先调度的抢占式策略
ThreadDemo th=new ThreadDemo();//新建状态,此时并不能被操作系统调度
th.start();//启动线程,不是启动后立即执行,进入到就绪状态,操作系统就可以调度
th.join();//让此线程加入到当前线程,等待此线程死亡
Thread.yield();//线程礼让 运行->就绪
并行:多个cpu同时执行多个任务(一个时间节点同时做多件事情)
并发:一个cpu(采用时间片)同时执行多个任务(一个时间段内,依次执行多个事情)
多线程 线程之间对共享资源进行访问时,会出现线程安全问题
static修饰的变量是类变量,在内存中只有一份
synchronized(同步对象){ }同步对象可以是任意类的对象,但是只能唯一的,只有一份的
对象中有一个区域叫对象头,对象头中有一个锁状态的记录
进入同步代码块 加锁 也就将对象头锁状态改为加锁
同步代码块执行完后,会自动释放锁 也就将对象头锁状态改为无锁
继承Runnable接口: synchronized(this){ } //由于出票任务类,只创建了一个对象,所以两个线程拿到的this是同一个
static Lock lock=new ReentrantLock();
try{
lock.lock();//加锁 锁标记在ReentrantLock对象维护
·
·
·
lock.unlock();
}catch(Exception e){
lock.unlock();
}
Synchronized 关键字 修饰代码块和方法 隐式的加锁、释放锁
底层实现靠虚拟机底层控制实现
Lock接口 ReentrantLock 实现类 ReentrantLock是类 只能修饰代码块
是显示地加锁、释放锁 只靠java代码控制实现
死锁 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需 要的同步资源
线程通信 通过线程间相互牵制实现线程之间切换执行 前提:必须是在同步代码块中使用
obj.wait(); //让线程等待,进入到阻塞状态,同时释放锁
obj.notify(); //唤醒wait()的线程
wait () //让线程等待,并释放锁,必须通过notify唤醒
//注意与sleep()的区别,sleep()是让线程休眠指定的时间,时间到了后进入到就绪状态
notify() //唤醒一个等待的优先级高的线程
notifyAll() //唤醒所有等待的线程
新增创建线程方式
实现Callable接口 与run()方法相比,有返回值;支持泛型的返回值;方法可抛出异常
需要借助FutureTask类接收任务
FutureTask<Intger> futureTask =new FutureTask();
Thread t = new Thread(futureTask);
t.start();