java学习笔记(?):多线程(上)

虽然我觉得详细但是别人不一定觉得详细的,关于Java多线程的知识点。


一、概述(程序、进程、线程

1.程序是一段静态的写好的代码以软件为例,下载下来的文件就是一段代码(即程序
2.进程是运行的程序通过程序的入口(如.exe) 可以运行程序,得到一个进程。多次运行同一个程序,得到多个不同的进程。
3.线程是独立运行的最小单元早期操作系统拥有资源和独立运行的最小单位是进程。随着发展,发明了线程。


二、Java实现多线程

多线程通过java.lang.Thread类来实现

  • 每个线程都是通过某个特定Thread对象的run()方法来实现的。run方法通常被称为线程体。
  • 通过Thread对象的start()方法来启动线程。直接调用run()方法,只是运行了一个普通方法。

2.1 继承Thread类实现多线程

//定义MyThread类继承Thread
public class MyThread extends Thread{
    @Override //重写run方法,线程中要做的事情都写在这里。
    public void run() {
        System.out.println("我的线程");
    }
}
public static void main(String[] args) {
	MyThread myThread = new MyThread();//创建实例
	myThread.start();//通过start方法启用线程
}

优点:实现简单 | 缺点:扩展性差

2.2 实现Runnable接口实现多线程

//实现Runnable接口
public class MyThread implements Runnable{
    @Override
    public void run() {
        System.out.println("我的线程");
    }
}
public static void main(String[] args) {
	MyThread myThread = new MyThread();//仍然是创建实例(但是可以理解成创建一个任务
	Thread thread = new Thread(myThread);//注意到这里把实例传入到了Thread的构造方法中(相当于把任务提交给thread去处理
	thread.start();//thread开始干活
}

优点:扩展性好 | 缺点:实现复杂

2.3 Thread生命周期和常用方法

生命周期顾名思义就是从诞生到消亡

  • 新建(New: 实例创建的时候,线程就诞生了。通过start()方法进入就绪状态
  • 就绪(Runnable: 这个时候具备了执行资格,但是还没有执行权。会不停的去抢占CPU。抢到手以后进入执行状态
  • 运行(Running: 线程开始执行。运行完毕,寿终正寝,进入死亡状态 | 被其他线程抢走了CPU的执行权进入就绪状态 | 阻塞方法,进入阻塞状态
  • 阻塞(Blocked: 被中止了运行,又回不到就绪状态。阻塞方法结束,进入就绪状态(只能进入就绪状态,运行状态的唯一入口是就绪状态
  • 死亡(Dead: 程序运行完毕或者被迫终止
String getName() //返回线程的名字 默认名字是Thread-X,X是第几个从0开始。
void setName(String name) //设置线程的名字,也可以用构造方法
static Thread currentThread() //获取当前线程的对象
static void sleep(long time) //让线程休眠指定时间,单位毫秒
setPriority(int newPriority) //设置线程的优先级
final int getPriority() //获取线程的优先级
final void setDaemon(boolean on) //设置为守护线程 //守护线程在非守护结束后也会陆续结束
public static void yield() //出让线程/礼让线程 //扔出后还会再抢
public static void join() //插入线程/插队线程
start()//设置要在开始前

三、线程安全

多个线程同时访问一个共享数据时,容易出问题,这个就是线程不安全

//这样子写,共享数据是test
public int test = 1;
public void run() {
	while(true){
		if(test > 0){//如果只有一个线程,那么什么问题都没有
			try {
				Thread.currentThread().sleep(20);//不管睡不睡,都会有其他线程也通过判断(因为这时候还没有对test进行修改。睡只是为了让效果更容易出现。
                test --;//每个通过判断的线程都会进行--操作,最终test的值小于0,和单线程的情况不一致
                System.out.println(test);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else{
			break;
        }
    }
}
public static void main(String[] args) {
    MyThread myThread = new MyThread();
    Thread thread_1 = new Thread(myThread);
    Thread thread_2 = new Thread(myThread);
    thread_1.start();
    thread_2.start();
}//输出结果有-1确实越界了(如果test代表唯一标识,还可能会出现重复。因此是不安全的

3.1 同步代码块synchronized

为了线程安全,对共享数据保证同一时刻只有一个进程进行访问
synchronized(Object o){ 需要控制的代码块儿 }//需要一个唯一的对象来当锁,可以用类名.class来当

public void run() {
    while(true){
        //将共享数据放进同步代码块,此时线程是安全的。(但是由于只能一个线程来访问,所以会降低运行效率
        synchronized (MyThread.class){
            if(test > 0){
                try {
                    Thread.currentThread().sleep(20);
                    test --;
                    System.out.println(test);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                break;
            }
        }
            
            
    }
}

3.2 同步方法

修饰符 synchronized 返回值类型 方法名(方法参数){方法体;}

//将同步代码块中的代码写在同步方法中,方法略有改动
public void run() {
    while(true){
    	if(!shell()){
    		break;
    	}  
    }
}
public synchronized Boolean shell(){//注意到和同步代码块的区别,不需要手动加锁了。
	boolean flag = true;
    if(test > 0){
        try {
            Thread.currentThread().sleep(20);
            test --;
            System.out.println(test);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }else{
        flag = false;
    }
    return flag;
}

创作不易,叹一会儿气

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值