java线程基础

一.多线程

a.大致内容

1.进程:在内存中执行的应用程序

2.线程:是进程中最小执行单元

线程作用:负责当前进程中程序的运行,一个进程至少有一个线程,一个进程中还可以有多个线程,简称:多线程

在这里插入图片描述

3.使用场景

软件中耗时操作->拷贝大文件,加载大量资源

所有聊天

后台服务器

一个线程可以干一件事,我们就可以同时干多件事,提高cpu利用率

b.并发和并行

1.并行:在同一时刻,有多个执行在多个cpu上同时惊进行


2.并发:在同一时刻,有多个指令在单个cpu上交替执行


detail:

1.之前cpu是单核的,但是执行多个程序的时候好像是在同时执行,原因是cpu在多个线程之间做高速切换

2.现在cpu是多核多线程的了,比如2核4线程,cpu可以同时运行4个线程,多了就要切换,所以现在cpu执行并发和并行都存在

c.CPU调度


1.分时调度:指的是让每个线程轮流获取cpu使用权,并且平均分配每个线程占用cpu的时间片

2.抢占模式多个线程轮流抢cpu使用权,优先级高抢到几率大,java用的这种

d.实现thread


1.extends Thread

1.定义一个类,继承tread
2.重写run方法设置线程任务(具体干的事,执行代码)
3.创建自定义线程类对象
4.调用tread中的start方法,开启线程
java

package tread_class;

public class thread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(i);
        }
    }
}


java
package tread_class;
public class test01 {
    public static void main(String[] args) {
        //创建线程对象
        thread thread = new thread();
        //调用start

        for (int i = 0; i < 10; i++) {
            System.out.println("main"+i);
        }
        thread.start();
    }
}

e.运行原理

在这里插入图片描述

f.常用方法

run()->设置线程任务
getname()->获取线程名字
setname()->设置名字
currentThread()->获取正在执行的线程对象
sleep()->线程睡眠,超时后自动醒来
	java
	package tread_class;

public class thread01 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            //sleep睡觉
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(i);
        }
    }
}

java
package tread_class;

public class test02 {
    public static void main(String[] args) {
        thread01 thread01 = new thread01();
        //设置名字
        thread01.setName("111");
        thread01.start();
        //获取
        System.out.println(thread01.getName());
        for (int i = 0; i <10 ; i++) {
            //获取当前线程
            System.out.println(Thread.currentThread().getName()+i);

        }
    }
}

问题:为啥在重写的run方法中有异常只能try不能throws
原因:继承的thread中的run方法中没有抛异常,所以子类重写后不能抛只能try

g.其他方法

setPriority(int newPriority)->设置线程优先级,不是一定是最先抢到的,提高几率
gettPriority->获取优先级
setDeamon()->守护线程->当非守护线程执行完毕,守护线程就要结束,但是守护线程也不会立马结束,系统返回需要时间
yield()->礼让线程
join()->插队线程,插入某线程之前
java
package mythread;

public class thread_02 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("thread"+currentThread().getName()+"........"+i);
        }
    }
}

java
package mythread;

public class test01 {
    public static void main(String[] args) {
        thread_02 thread02 = new thread_02();
        thread02.setName("t1");
        thread_02 thread03 = new thread_02();
        thread03.setName("t2");
        System.out.println(thread02.getPriority());
        System.out.println(thread03.getPriority());
        thread03.setPriority(1);
        thread02.setPriority(10);
        thread03.start();
        thread02.start();
    }
}
java
package mythread.protest;

public class mythread02 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(currentThread().getName()+"/"+i);
        }
    }
}
package mythread.protest;

public class mythread01 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"......."+i);

        }
    }
}
package mythread.protest;

public class mythread02 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(currentThread().getName()+"/"+i);
        }
    }
}

g.1第二种方式实现Runnable接口

1.创建类实现runnabe接口
java
package mythread.runnable;

public class myrunable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"......"+i);
        }
    }
}

2.重写run方法,设置线程任务
3.利用thread构造方法:Thread(Runnable target)
java
package mythread.runnable;

public class Test01 {
    public static void main(String[] args) {
        myrunable myrunable = new myrunable();
        Thread t1=new Thread(myrunable);
        t1.start();
    }
}

4.调用start

f两种线程区别

	继承只支持单继承
	Runnable:没有继承局限性,可以多继承

h匿名内部类创建多线程

	匿名内部类回顾
	1.new接口()/抽象类()
	{
	重写方法
	}.重写方法();
	2.接口名/类名 对象名=new 接口/抽象类(){
	重写方法
	}
	对象名.方法();
java
public class test01 {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++)
                {
                    System.out.println(Thread.currentThread().getName()+i);
                }
            }
        }.start();

    }
}

m安全

在这里插入图片描述

java
public class mytickt implements Runnable{
    int tickt=100;
    @Override
    public void run() {
        while (true) {
            if (tickt > 0) {
                System.out.println(Thread.currentThread().getName() + "买到票了" + tickt + "票");
                tickt--;
            }
        }
    }

}
public class Test02 {
    public static void main(String[] args) {
        mytickt mytickt = new mytickt();
        Thread t1=new Thread(mytickt,"赵四");
        Thread t2=new Thread(mytickt,"张三");
        Thread t3=new Thread(mytickt,"王五");
        t1.start();
        t2.start();
        t3.start();
    }
}



解决方法一(上锁)(使用同步代码块)
  • 1.格式
    • synchronized(任意对象){
      线程可能出现不安全}
  • 2.任意对象:即是锁对象
  • 3.执行:
    • 抢到锁就执行,没有就等待
    
    
java

package mythread.change_security;

public class  mytickt implements Runnable{
    int tickt=100;
    //任意new一个对象
    Object obj =new Object();
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized (obj)
            {
            if (tickt > 0) {
                System.out.println(Thread.currentThread().getName() + "买到票了" + tickt + "票");
                tickt--;
            }
        }
        }
    }

}
public class Test02 {
    public static void main(String[] args) {
        mytickt mytickt = new mytickt();
        Thread t1=new Thread(mytickt,"张三");
        Thread t2=new Thread(mytickt,"赵四");
        Thread t3=new Thread(mytickt,"王五");
        t1.start();
        t2.start();
        t3.start();
    }
}

解决方法二
非静态
  •   在Runnale接口类中写一个单独的方法
    
  •   默认锁对象是this
    
java
package mythread.change_security;
public class  mytickt implements Runnable{
    static int tickt=100;
    //任意new一个对象
    Object obj =new Object();
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        method();
        }
    }
    public static void method()
    {
        if (tickt > 0) {
            System.out.println(Thread.currentThread().getName() + "买到票了" + tickt + "票");
            tickt--;
        }
    }
    

}


静态
1.格式:
修饰符 static synchronized 返回值类型 方法名(参数){
	方法体
}
return 结果
2.默认值:class对象

h死锁

在这里插入图片描述

静态
1.格式:
修饰符 static synchronized 返回值类型 方法名(参数){
	方法体
}
return 结果
2.默认值:class对象

g生命周期

1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
  1. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  2. 阻塞(BLOCKED):表示线程阻塞于锁。
  3. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
  4. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
  5. 终止(TERMINATED):表示该线程已经执行完毕。
    ————————————————

原文链接:更多请点击

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值