1、线程
进程:OS中并发的一个任务。
CPU分时间片 宏观并行 微观串行 由OS负责调度
线程:在一个进程中,并发的一个顺序执行流程。
线程的组成:
1)CPU 由OS负责调度
2)Data 堆空间共享 栈空间独立
堆空间:存储对象(存储实例变量)
栈空间:存储局部变量
3)Code 由程序员指定
一个Thread对象代表一个线程
继承Thread类
实现Runnable接口
线程是OS维护的一种资源。
线程对象在虚拟机当中。
Runnable
package chp12;
public class TestThread {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread t1=new ThreadA();
Runnable target=new Target();//目标对象不是线程对象,但可以构造线程对象
Thread t2=new Thread(target);
t1.start(); //请求操作系统,新的线程启动
t2.start();
}
}
class ThreadA extends Thread{
public void run(){
for(int i=0;i<=10000;i++){
System.out.println("$$$"+i);
}
}
}
class Target implements Runnable{
public void run(){
for(int i=0;i<=10000;i++){
System.out.println("###"+i);
}
}
}
什么叫做转方法。。。就是并行变串行
t1:t2.join() t1阻塞 当t2进入中止状态时,t1回到可运行状态
初始状态:
可运行状态:调用start 只欠CPU
运行状态:OS选中
终止状态:run方法退出
阻塞状态:1)等待数据输入
2)sleep
3)join
线程同步:
当多线程并发访问临界资源(同一个对象)时,如果破坏了原子操作(不可分割的操作),就会造成数据不一致。
synvhronized(o){}:对o加锁的同步代码块
任何对象都有一个互斥锁标记,用来分配给线程
只有拿到对象锁标记的线程,才能进入对该对象加锁的同步代码块
线程退出同步代码块,会释放相应的锁标记
同步方法:在整个方法的范围内,对当前对象加锁
只有拿到对象锁标记的线程,才能调用该对象的同步方法
锁池:任何对象都有的一个空间,用来存放等待该对象锁标记的线程
一个线程可以同时拥有多个锁标记
线程间通信:等待-通知
任何对象都有一个等待队列,用来存放线程
Object
wait()
notify()
t1:o.wait() 必须放在对o加锁的同步代码块中
t1会释放其拥有的所有锁标记;同时 t1会阻塞在o的等待队列中
t2: o.notify()/notifyAll()必须放在对o加锁的同步代码块中,从o的等待队列中释放一个/全部线程。
ArrayList :所有的方法都不是同步方法
和 Vector :所有的方法都是同步方法 安全 效率低
修饰符组合:
synchronized 和 statics 联用:可以 给当前的类对象加锁
synchronized和 abstract 联用:不可以
构造方法和synchronized 联用:不可以
创建线程的2种方法:
java中创建一个线程有两种方式:
1、继承Thread类,重写run()方法,然后直接new这个对象的实例,创建一个线程的实例。然后调用start()方法启动线程
2、实现Runnable接口,重写run()方法,然后调用new Thread(runnable)的方式创建一个线程,然后调用start()方法启动线程
其实看Thread的源文件,发现它也是实现了Runnable接口的。