1、进程,线程的特性:
进程概念:
1.独立性
2.互斥性
线程概念:
线程是进程最小的基本单位.
特性:
1.抢占式运行
2.资源共享
2、线程的两种创建方式:
方法1:
创建一个新的执行线程有两种方法。 一个是将一个类声明为`Thread`的子类。 这个子类应该重写`run`方法`Thread` 。 然后可以分配并启动子类的实例。
1.声明一个类继承Thread
2.重写run方法
3.新建线程的实例
4.start()启动线程
方法2:
另一种方法来创建一个线程是声明实现类`Runnable`接口。 那个类然后实现了`run`方法。 然后可以分配类的实例,在创建`Thread`时作为参数传递,并启动。
1.声明一个类实现Runnable
2.重写run方法
3.新建线程的实例
4.传参给新建Thread实例
5.start()启动线程
3、Thread线程的方法
Thread构造方法:
方法1无参构造:
Thread t = new Thread();
方法2分配一个新的Thread对象:
Thread t = new Thread(new 类名());
方法3分配一个新的Thread对象. 并对这个线程起一个名字
Thread t = new Thread(new 类名(),"线程名字")
Thread方法:
.currentThread()//返回当前正在执行的线程对象的引用
.getName()//返回此线程的名称
.setName(String name)//将此线程的名称更改为参数name
.getPriority()//返回此线程的优先级
.setPriority()//更改此线程的优先级
Thread.sleep(long millis)//使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。需要try,catch
4、线程同步和锁
锁方法
public synchronized void eat(){
}
//只有一个线程能进入方法中,其他的在外面等
锁代码块
synchronized (锁对象){
}
//锁住的对象,最好是唯一的,优先可考虑的本类的Class对象
因为线程是抢占式执行,又是资源共享的,同时操作同一个数据,可能会污染数据,这是不安全的
5、死锁
当线程A锁住了线程B想要的资源,线程B锁住了A想要的资源,就形成了死锁
class DeadLock extends Thread {
boolean flag = true;
Object obj1;
Object obj2;
public DeadLock (flag, obj1, obj2){
this.flag = flag;
this.obj1 = obj1;
this.obj2 = obj2;
}
public void run (){
if(flag){
synchronized (obj1){
sout("线程A执行,接下来锁住B要的资源");
synchronized (obj2){
sout("释放资源,让B执行");
}
}
}else {
synchronized (obj2){
sout("线程B执行,接下来锁住A要的资源");
synchronized (obj1){
sout("释放资源,让A执行");
}
}
}
}
}
public class TestDeadLock {
public static void main (String[] args){
Object o1 = new Object();
Object o2 = new Object();
new DeadLock(true, o1, o2).start();
new DeadLock(false, o1, o2).start();
}
}
6、Object类下面的和线程相关的方法
public final void wait() throws InterruptedException .wait()//让线程等待,等待notify执行 .notify()//唤醒一个等待线程 .notifyAll()//唤醒说有等待线程
7、线程的生命周期
- 线程的创建启动 start();
- 线程的可运行状态 抢占
- 线程的运行状态 抢占和执行
- 线程的阻塞 wait(); sleep(); 锁
- 线程的消亡 destroy
8.Join方法
让主线程(相对于)等待,让子线程先执行,执行完子线程在执行主线程
9.7种线程池
主要用一个ThreadPoolExecutor,有7个参数,前5个分别是
核心线程数
最大线程数
存活时间
存活时间的单位
阻塞队列
剩下两个参数是拒绝策略,有默认值
阻塞队列,有两个:ArrayBlockingQueue、LinkedBlockingQueue
10、生产者,消费者模式
class A{
private String name;
private double jiaGe;
private boolean isPanduan;
public A(String name, double jiaGe, boolean isPanduan) {
this.name = name;
this.jiaGe = jiaGe;
this.isPanduan = isPanduan;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getJiaGe() {
return jiaGe;
}
public void setJiaGe(double jiaGe) {
this.jiaGe = jiaGe;
}
public boolean isPanduan() {
return isPanduan;
}
public void setPanduan(boolean panduan) {
isPanduan = panduan;
}
}
class XiaoFeiZhi implements Runnable{
private A a;
public XiaoFeiZhi(A a) {
this.a = a;
}
@Override
public void run() {
while(true){
synchronized (a){
if (!a.isPanduan()){
System.out.println("消费者购买了:"+a.getName()+"价格为:"+a.getJiaGe());
a.setPanduan(true);
System.out.println();
a.notifyAll();
}else{
try {
a.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Shengchanzhe implements Runnable{
private A a;
public Shengchanzhe(A a) {
this.a = a;
}
@Override
public void run() {
int count =0;
while (true){
synchronized (a){
if (a.isPanduan()){
if (count % 2 == 0){
a.setName("面包");
a.setJiaGe(5.5);
}else{
a.setName("水");
a.setJiaGe(3.99);
}
System.out.println("生产者生产了:"+a.getName()+"价格为:"+a.getJiaGe());
a.setPanduan(false);
count++;
a.notifyAll();
}else{
try {
a.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public class WhitNotify {
public static void main(String[] args) {
A a = new A("食物",1,true);
Shengchanzhe shengchanzhe = new Shengchanzhe(a);
XiaoFeiZhi xiaoFeiZhi = new XiaoFeiZhi(a);
new Thread(shengchanzhe).start();
new Thread(xiaoFeiZhi).start();
}
}