博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java高并发之从零到放弃(二)
阅读量:6448 次
发布时间:2019-06-23

本文共 3526 字,大约阅读时间需要 11 分钟。

前言

java高并发第二篇讲的是java线程的基础

依旧不多说废话

线程和进程

进程是操作系统运行的基础,是一个程序运行的实体,windows上打开任务管理器就能看到进程

线程是轻量级的进程,是程序执行的最小单位,是在进程这个容器下进行的

线程基本操作

新建一个线程类有两种方式:extends Threadimplement 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释放监听器,那个被唤醒的线程就会进来

用图更形象:

clipboard.png

  • 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,只管执行打印代码:

clipboard.png

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

clipboard.png

现在很容易理解了,因为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定义的对象的值是不可变的

今天就先到这里,大家可以看看这些内容的拓展

记得点关注看更新,谢谢阅读

转载地址:http://yrlwo.baihongyu.com/

你可能感兴趣的文章
如何把老旧笔记本变成一部 Chromebook
查看>>
阿里云肖力:专业云计算服务商有能力提前解决勒索病毒隐患
查看>>
Linux下打包压缩war、解压war包和jar命令
查看>>
Vertica的这些事&lt;六&gt;—— SQL Server、Oracle、MySQL和Vertica数据库常用函数对比...
查看>>
《C语言及程序设计》实践参考——复数结构体
查看>>
舆情中的热词分析,没你想的那么简单
查看>>
常见监控工具说明
查看>>
数据结构例程——迷宫问题(用栈结构)
查看>>
定时 监控 shell 服务宕机自动重启,并发送短信通知
查看>>
HttpComponents (http 客户端) 常用类简介
查看>>
【D3.js 学习总结】14、D3布局-打包图
查看>>
PostgreSQL DDL事件触发器
查看>>
SecureCRT光标丢失问题
查看>>
2016美国旧金山QCon:参会后记
查看>>
10分钟掌握数据库建模
查看>>
流媒体02:Linux交叉编译VLC-2.2.1
查看>>
log_format directive may be used only on http level
查看>>
Magento API v1 之webservice
查看>>
hibernate 模糊查询及not in子查询
查看>>
图像处理------ 二值膨胀及应用
查看>>