资讯专栏INFORMATION COLUMN

java高并发之从零到放弃(二)

cloud / 2458人阅读

摘要:可以用代替可以用代替定义的对象的值是不可变的今天就先到这里,大家可以看看这些内容的拓展记得点关注看更新,谢谢阅读

前言

java高并发第二篇讲的是java线程的基础
依旧不多说废话

线程和进程

进程是操作系统运行的基础,是一个程序运行的实体,windows上打开任务管理器就能看到进程
线程是轻量级的进程,是程序执行的最小单位,是在进程这个容器下进行的

线程基本操作
新建一个线程类有两种方式:
extends Thread
implement Runnable

推荐使用Runnable接口(这不废话吗)

1.创建线程

Thread t1 = new Thread(){
    @Ovveride
    public void run(){
        System.out.println("create");
    }
t1.start();

重构run()方法,用start()启动线程

2.终止线程

Thread.stop();

不推荐stop,强行终止不能保证原子性
这里给大家写一个终止线程的推荐方法:

public class interruptTest {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(){
            public void run(){
                while (true){
                    System.out.println("go");
                    if (Thread.currentThread().isInterrupted()){
                        break;
                    }
                }
            }
        };
        t1.start();
        Thread.sleep(10001);
        t1.interrupt();
    }
}

看懂了吗?
方法解释:
interrupt和stop不同的是,stop会立即中断线程,而interrupt的中断线程由线程自己决定

Thread.interrupt()        //设置中断标志
Thread.isInterrupted()        //判断当前线程是否有中断标志,如果有,返回true

sleep()也能让线程暂时性的中断,即让线程休眠

3.线程协作之等待和通知

多线程之间的协作可以使用等待(wait())和通知(notify)进行
wait和notify不能乱用,它们必须包含在synchronzied(即同步)的方法中
无论是wait还是notify,都需要一个目标对象的监听器(也叫锁)

当线程1在一个同步的object对象中运行的时候,突然执行object.wait()方法,此时线程停止执行,并且退出object对象,释放对象的监听器,线程1进入等待队列
接着线程2进入object对象,首先拿到object对象的监听器,当线程2执行object.notify()方法时,对象object会随机选择一个等待队列中的线程,并将其唤醒,然后线程2释放监听器,那个被唤醒的线程就会进来

用图更形象:

4.线程协作之结束和谦让

多线程之间的协作可以使用结束(join())和谦让(yield())进行
join()方法就是让一个线程加入到另一个线程,至于怎么个加入法看下面一个例子:

public class JoinTest {
    public volatile static int i=0;
    public static class JoinThread extends Thread{
        @Override
        public void run(){
            for (i=0;i<1000;i++){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        JoinThread joinThread = new JoinThread();
        joinThread.start();
        System.out.println(i);
    }
}

这个方法打印出来的i大家肯定知道,一定是0,因为我们在这个类的主线程里执行,虽然joinThread和主线程一起执行了,但是主线程并不会去理会joinThread,只管执行打印代码:

再来看看加入join()后的结果:

现在很容易理解了,因为joinThread线程加入到了主线程中,joinThread的join()让主线程去等待它完成才执行打印,所以会打印出1000

yield()是谦让,字面意思,就是我已经完成一些最重要的事情了,不想再占着CPU资源,需要休息啊一下,但是能否被分配到CPU资源就不一定了

守护线程

守护线程是在后台默默完成系统服务的线程,如垃圾回收线程,JIT线程
与之相应的是用户线程,也就是用户完成业务要用的线程
当一个java程序中只剩守护线程的时候,JVm就会自然退出
下面用一段代码证明:
代码new Thread().setDaemon(true);就是设置为守护线程

public class DaemonTest {

    public static class DaemonT extends Thread{
        public void run(){
            while (true){
                System.out.println("我还在");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
            }
        }
    }


    public static void main(String[] args) throws InterruptedException {
        DaemonT daemonT = new DaemonT();
        daemonT.setDaemon(true);
        daemonT.start();
        Thread.sleep(2000);
    }
}

上面代码在主线程运行两秒后,自动关闭应用,因为只有守护线程

线程优先级设置

java的线程优先级可以用1-10表示
数字越高表示优先级越高

Thread thread1 = new Thread();
thread.setPriority(10);

这样thread1线程的优先级就是最高的

线程安全与synchronized

为了保证线程安全,我们之前讲过可以使用volatile保证变量可见性
但是volatile并不能真正的保证线程的安全
使用synchronized保证线程安全,synchronized会在对象上加锁
使同一时间只能有一个线程进入该对象
synchronized的用法整理:

指定加锁对象:对给定对象加锁,进入同步代码前获得给定对象的锁
直接作用于实例方法:相当于对当前实例加锁
直接作用于静态(static)方法,相当于给当前类加锁

所以要注意在同个线程指定的监听对象是new Test()还是test实例

Tips

HashMap的多线程编程是不安全的,可能导致机子死机,两个线程交互next会进入死循环。可以用ConcurrentHashMap代替
ArrayList可以用Vector代替
Integer定义的对象的值是不可变的

今天就先到这里,大家可以看看这些内容的拓展
记得点关注看更新,谢谢阅读

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70635.html

相关文章

  • java并发之从零到放弃(一)

    摘要:今天就先到这里,大家可以看看这些内容的拓展记得点关注看更新,谢谢阅读 前言 这是一个长篇博客,希望大家关注我并且一起学习java高并发废话不多说,直接开始 并行和并发 并行:多个线程同时处理多个任务并发:多个线程处理同个任务,不一定要同时 下面用图来描述并行和并发的区别:(实现和虚线表示两个不同的线程) showImg(https://segmentfault.com/img/bVYT...

    luoyibu 评论0 收藏0
  • java并发之从零到放弃(三)

    摘要:前言今天讲的多线程的同步控制直接进入正题重入锁重入锁可以完全代替,它需要类来实现下面用一个简单的例子来实现重入锁以上代码打印出来的是,可以说明也实现了线程同步它相比更加灵活,因为重入锁实现了用户自己加锁,自己释放锁记得一定要释放,不然其他线 前言 今天讲的多线程的同步控制直接进入正题 ReentrantLock重入锁 重入锁可以完全代替synchronized,它需要java.util...

    FrozenMap 评论0 收藏0
  • java并发之从零到放弃(五)

    摘要:前言这篇主要来讲解多线程中一个非常经典的设计模式包括它的基础到拓展希望大家能够有所收获生产者消费者模式简述此设计模式中主要分两类线程生产者线程和消费者线程生产者提供数据和任务消费者处理数据和任务该模式的核心就是数据和任务的交互点共享内存缓 前言 这篇主要来讲解多线程中一个非常经典的设计模式包括它的基础到拓展希望大家能够有所收获 生产者-消费者模式简述 此设计模式中主要分两类线程:生产者...

    meislzhua 评论0 收藏0
  • java并发之从零到放弃(四)

    摘要:前言本篇主要讲解如何去优化锁机制或者克服多线程因为锁可导致性能下降的问题线程变量有这样一个场景,前面是一大桶水,个人去喝水,为了保证线程安全,我们要在杯子上加锁导致大家轮着排队喝水,因为加了锁的杯子是同步的,只能有一个人拿着这个唯一的杯子喝 前言 本篇主要讲解如何去优化锁机制或者克服多线程因为锁可导致性能下降的问题 ThreadLocal线程变量 有这样一个场景,前面是一大桶水,10个...

    Alex 评论0 收藏0
  • 前端从零开始系列

    摘要:只有动手,你才能真的理解作者的构思的巧妙只有动手,你才能真正掌握一门技术持续更新中项目地址求求求源码系列跟一起学如何写函数库中高级前端面试手写代码无敌秘籍如何用不到行代码写一款属于自己的类库原理讲解实现一个对象遵循规范实战手摸手,带你用撸 Do it yourself!!! 只有动手,你才能真的理解作者的构思的巧妙 只有动手,你才能真正掌握一门技术 持续更新中…… 项目地址 https...

    Youngdze 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<