多线程_学习

1、多线程

1.2进程和线程

​ 进程
​ 正在运行的程序的实例
​ 线程
​ 进程的执行单元

1.3继承Thread类实现多线程

​ 1.定义一个类,继承Thread类
​ 2.重写run方法,设置线程任务
​ 3.创建线程任务类对象
​ 4.通过线程任务类对象调用start方法,开启线程

1.4设置和获取线程名称

​ 1.4.1设置
​ Threa(String name)
​ 通过Thread类的构造方法设置
​ void setName(String name)
​ 通过Thread类的setName方法设置
​ 1.4.2获取
​ String getName()
​ 通过Thread类的成员方法getName获取
​ Thread.currentThread().getName()
​ 通过Thread类的静态方法获取当前线程对象,之后再获取线程名称

package com.itfenghua01;
//继承线程,重写run方法,实现构造方法
public class myThream extends Thread {
    public  myThream(){}
    public  myThream(String name){
        super(name);

    }
    @Override
    public void run() {
        for (int i = 0; i < 99; i++) {

            System.out.println(getName()+","+i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

----------------------------------
package com.itfenghua01;

public class threadDemo {
    public static void main(String[] args) {
        myThream mt1 = new myThream("石");
        myThream mt2 = new myThream();

        mt2.setName("玉");
        String name = Thread.currentThread().getName();
        System.out.println(name);
        mt1.start();
        mt2.start();
    }
}


1.5设置和获取线程优先级

​ void setPriority(int newPriority)
​ 设置线程优先级,从1到10,越来越高,默认是5
​ int getPriority()
​ 获取线程的优先级

1.6线程控制

​ void sleep(long time)
​ 让当前线程休眠指定时间
​ void join()
​ 等待当前线程终止
​ void setDaemon(boolean on)
​ 将当前线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出

1.7线程生命周期

​ 新建
​ 就绪
​ 运行
​ 阻塞
​ 死亡

1.8实现Runnable接口实现多线程

​ 1.8.1步骤
​ 1.定义一个类,实现Runnable接口
​ 2.重写run方法,设置线程任务
​ 3.创建任务类对象
​ 4.创建线程类对象,构造方法传入任务类对象
​ 5.通过线程类的start方法,开启线程
​ 1.8.2好处
​ 1.避免了单继承的局限性
​ 2.降低了程序的耦合性,提高了程序的拓展性

2、线程安全

2.1线程安全问题产生原因

​ 1.是多线程
​ 2.有共享数据
​ 3.有多条语句操作共享数据

2.2同步代码块

​ 2.2.1格式
​ synchronized(锁对象){
//多条语句操作共享数据的代码
}
​ 2.2.2锁对象
​ Object obj = new Object
​ 任意对象
​ this
​ 当前对象
​ 类名.class
​ 对应的类的Class对象(一个类的Class对象多次获取是同一个)
​ 注意
​ 要保证线程安全,多个线程必须使用同一把锁
​ 2.2.3好处和弊端
​ 好处:解决了多线程的数据安全问题
​ 弊端:频繁的判断锁,获取锁,释放锁,会降低程序的运行效率

package com.itfenghua03;

public class shellTekits implements Runnable {
    private static int tickits = 100;
    //表示任意对象
    private Object obj = new Object();

    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                if (tickits > 0) {
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在卖第" + tickits + "张票");
                    tickits--;
                } else {
                   // shelltt();
                    shellkk();
                }
            }
        }
    }
//类名.class全局只有一个做锁
    private static synchronized void shellkk() {
        if (tickits > 0) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在卖第" + tickits + "张票");
            tickits--;
        }
    }



    //锁使用this代表同一把锁
    private  void shelltt() {
        synchronized (this)

        {
            if (tickits > 0) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "正在卖第" + tickits + "张票");
                tickits--;
            }
        }
    }
}
2.3同步方法

​ 2.3.1格式
​ 修饰符 synchronized 返回值类型 方法名(){
//多条语句操作共享数据的代码
}
​ 2.3.2注意事项
​ 1.普通同步方法的锁对象是this
​ 2.静态同步方法的锁对象是类名.class

2.4Lock锁

​ 2.4.1介绍
​ JDK1.5之后出现的,在产生安全问题代码前获取锁,在产生安全问题代码后释放锁
​ 2.4.2使用步骤
​ Lock lock = new ReentrantLock()
​ 创建锁对象
​ lock.lock()
​ 获取锁对象
​ lock.unlock()
​ 释放锁对象
​ 2.4.3注意
​ 任何情况下都要释放锁对象

package cx.itfenghua02;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class lockRun implements Runnable{
    private int tickets = 100;
    private Lock lock = new ReentrantLock();
    @Override
    public void run() {
while (true){
    lock.lock();
    if (tickets>0){
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"正在卖第"+tickets+"斤猪肉");
        tickets--;
    }else {
        break;
    }
    lock.unlock();
}
    }
}

3、等待与唤醒

3.1方法

​ void wait()
​ 让当前线程进入等待状态
​ void notify()
​ 唤醒在此对象监视器上等待的单个线程
​ void notifyAll()
​ 唤醒在此对象监视器上等待的所有线程

3.2注意事项
			1.可以使用任意对象调用wait和notify方法,因为任意对象都继承Object

​ 2.必须使用锁对象并且是同一把锁对象调用wait和notify才有意义
​ 3.必须在同步方法或者同步代码块内调用wait和notify才有意义

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值