java线程总结==王小虎

线程

新建线程和main线程枪托cpu执行权

在这里插入图片描述多线程内存图解在这里插入图片描述实现runnable接口创建多线程的好处:
1.避免了单继承的局限性
一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类
实现了runnable接口还可以继承其他的类,实现其他的接口
2.增强了程序的扩展性,降低了程序的耦合性
实现runnable接口的方式,把设置线程任务和开启线程进行了分离
实现类中重写了run方法,用来设置线程任务
创建Thread类对象,调用start方法,用来开启新线程
并发与并行
并发:指的是两个事件,在同一时间段内发生(交替执行)
并行:指的是两个事件,在同一时刻发生(同时执行)
进程和线程
进程,进入到内存的程序叫进程,一个程序运行后至少有一个进程,一个进程中可以包含多个线程
线程:线程是进程的一个执行单元,负责当前进程中的程序的执行,含有多个线程的程序也叫做多线程程序。在这里插入图片描述进程和线程图解
在这里插入图片描述线程调度
分时调度:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间
抢占式调度:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么随机选择一个,java使用的为抢占式调度
线程优先级可以自行设置
主线程:执行主方法的线程
单线程程序:java程序中只有一个线程,执行从main方法开始,从上到下依次执行

如何创建一个线程?
1.创建一个类MyThread,继承Thread类
2.重写Thread类中的run方法
3.创建MyThread类的对象,开启线程
举例:
public class MyThread extends Thread {

@Override
public void run() {

    for (int i = 0 ; i<20; i++){
        System.out.println("run"+i);
    }
}

}

public class Main {

public static void main(String[] args)  {

    MyThread myThread = new MyThread();
    myThread.start();

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

}

线程安全问题(不允许产生,要想办法,不让安全问题产生)
多线程访问了共享的数据,就会产生线程安全问题
举例:
public class RunnableImp implements Runnable {
private int ticket = 100;//共享数据
@Override
public void run() {
while (true){
if (ticket > 0 ){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+“正在售卖第”+ticket+“张票”);
ticket–;
}
}
}
}

public class Main {

public static void main(String[] args)  {

    Runnable runnable = new RunnableImp();


    Thread thread1 = new Thread(runnable);
    Thread thread2 = new Thread(runnable);
    Thread thread3 = new Thread(runnable);

    thread1.start();
    thread2.start();
    thread3.start();

}

}

解决线程安全问题
为了保证每个线程都正常执行原子操作,java引入了线程同步机制
1.同步代码块
2.同步方法
3.锁机制

同步代码块

同步技术的原理:

synchronized(锁对象){
可能 出现线程安全问题的代码(访问了共享数据的代码)
}
注意:1.通过代码块中的锁对象, 可以使用任意的对象
2.但是必须保证多个线程使用的锁对象是同一个
3.锁对象作用:
把同步代码块锁住,只让一个线程在同步代码块中执行
举例如下(还是卖票问题):

public class RunnableImp implements Runnable {
private int ticket = 100;//共享数据
Object object = new Object();
@Override
public void run() {
while (true){
synchronized (object){ //此处为synchronized锁,里面放的是访问了共享数据的代码块
if (ticket > 0 ){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+“正在售卖第”+ticket+“张票”);
ticket–;
}
}
}
}
}
同步技术原理(同步代码块学的)
在这里插入图片描述同步方法
使用步骤:
1.把访问了共享数据的代码抽取 出来,放到一个方法中
2.在方法上添加synchronized修饰符
格式:定义同步方法的格式
修饰符 synchronized 返回值类型 方法名 (参数列表){
可能会出现线程安全问题的代码(访问了共享数据的代码)
}

示例如下:
public class RunnableImp implements Runnable {
private int ticket = 100;//共享数据
@Override
public void run() {
while (true) {
ticket();
}
}
public synchronized void ticket(){
if (ticket > 0 ){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+“正在售卖第”+ticket+“张票”);
ticket–;
}
}

锁机制(解决线程安全问题的第三种方法)
Lock()获取锁
unlock()释放锁
使用步骤:
1.在成员位置创建一个Reentrantlock对象
2.在可能出现安全问题的代码钱调用lock接口中的方法lock获取锁
3.在可能出现安全问题的代码块后调用lock接口的方法unlock释放锁

示例如下:
public class RunnableImp implements Runnable {
private int ticket = 100;//共享数据

Lock lock = new ReentrantLock();
@Override
public void run() {
    while (true) {
        lock.lock();			//获取锁

        if (ticket > 0 ){
            try {
                Thread.sleep(10);
                System.out.println(Thread.currentThread().getName()+"正在售卖第"+ticket+"张票");
                ticket--;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();			//释放锁
            }
        }
    }
}

等待唤醒机制(有效的利用cpu资源)
线程间通信:多个线程处理同一个资源,但是处理的动作(线程的任务)却不同。(生产包子和吃包子)
wait();等待
notify()唤醒
线程状态
在这里插入图片描述线程池
JDK1.5后java已经内置了线程池,不需要自己通过集合的方式创建了
java.util.concurrent.Executors:线程池的工厂类,用来生产线程池
线程池的使用步骤:
1.使用线程池的工厂类executors里面提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池
2.创建一个类,实现Runnable接口,重写run方法,设置线程任务
3.调用executorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法
4.调用ExecutorService中的方法shutdown销毁线程池(不建议执行)

//创建一个类,实现Runnable接口,重写run方法,设置线程任务
public class RunnableImp implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+“创建了一个线程”);
}
}

public class Main {
public static void main(String[] args) {
//使用线程池的工厂类Executors里面提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
//3.调用executorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法
executorService.submit(new RunnableImp());
executorService.submit(new RunnableImp());
executorService.submit(new RunnableImp());
//4.调用ExecutorService中的方法shutdown销毁线程池(不建议执行)
executorService.shutdown();
}
}
//执行结果
pool-1-thread-1创建了一个线程
pool-1-thread-1创建了一个线程
pool-1-thread-2创建了一个线程

至此,线程部分结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值