多线程深入话题

1,优雅的停止线程

  在多线程操作之中如果要启动多线程使用的肯定是Thread类中的start()方法,而如果对于多线程需要进行停止处理,Thread类原本提供有stop()方法,但是这些方法从JDK1.2版本就已经将其废弃【@Deprecated】了,而且一直到现在也不在建议出现在代码之中。

停止多线程

public void stop()

销毁多线程

public void destroy()

挂起线程

public final void suspend()暂停执行

恢复挂起的线程执行

public final void resume()

  之所以废除这些方法,主要的原因是因为这些方法有可能导致线程的死锁,所以从JDK1.2开始就都不建议使用了。如果现在要想实现线程的停止需要通过一些柔和的方式来进行。

  ·范例:实现线程柔和的停止

 public class Main {
public static boolean flag=true;
public static void main(String[] args) throws InterruptedException{
new Thread(()->{
long num=0;
while (flag){
try{
Thread.sleep(50);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在运行,num="+num++);
}
},"执行线程").start();
Thread.sleep(200);
flag=false;
}
}

  备注:现在这种方法是解决循环死锁最好用也是最方便的方法。  万一现在有其他线程去控制这个flag的内容,那么这个时候对于线程的停止也不是说停就立刻停止的,而是在运行中判断flag的内容来决定。

2,后台守护线程

  现在假设有一个人并且这个人有一个保镖,那么这个保镖一定是在这个人活着的时候进行守护,如果这个人已经死了,保镖没有用了。所以在多线程里面可以进行守护线程的定义,也就是说如果主线程的程序或者其它的线程还在执行的时候,那么守护线程将一直存在,并且运行在后台的状态。

  在Thread类里面提供有如下的守护线程的操作方法:

  ·范例:使用守护线程

 public class Main {
public static boolean flag=true;
public static void main(String[] args) throws InterruptedException{
Thread userThread = new Thread(()->{
for(int x=0;x<10;x++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在运行,x="+x);
}
},"用户线程");//完成核心的业务
Thread daemonThread = new Thread(()->{
for(int x=0;x<Integer.MAX_VALUE;x++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在运行,x="+x);
}
},"守护线程");//完成核心的业务
daemonThread.setDaemon(true);
userThread.start();
daemonThread.start();
}
}

3,volatile关键字

  可以发现所有的守护线程都是在围绕用户线程的周围,如果程序执行完毕了,守护线程也就消失了,在整个JVM里面最大的守护线程就是GC线程!对啊,程序都完结了,那么该守护线程GC也就没有存在的意义了。

  在多线程的定义之中,volatile关键字主要是在属性定义上使用的,表示此属性为直接数据操作,而不是进行副本的拷贝处理,这样的话,在一些书上就错误的将其理解为同步属性。

  在正常进行变量处理的时候往往会经历如下的几个步骤:

    ①获取变量原有的变量内容副本;

    ②利用副本为变量进行数学计算;

    ③将计算后的变量,保存到原始空间之中;

  而一个属性上追加了volatile关键字,表示不使用副本,而是直接操作相当于节约:拷贝副本、重新保存的步骤。

  ·范例:volatile正确用法【与同步没有什么关系,只与更快的数据存取有关】

 class MyThread implements Runnable{
private volatile int ticket=5;//直接内存操作
@Override
public void run() {
synchronized(this){
while (this.ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖票处理,ticket="+this.ticket--);
}
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException{
MyThread mt=new MyThread();
new Thread(mt,"票贩子A").start();
new Thread(mt,"票贩子B").start();
new Thread(mt,"票贩子C").start();
}
}

  ①volatile主要在属性上使用,而synchronized是在代码块与方法上使用的;面试题:请解释volatile与synchronized的区别?

  ②volatile无法描述同步的处理,它只是一种直接的内存处理,避免了副本的操作,而synchronized是实现同步的。

进阶Java编程(4)多线程深入话题的更多相关文章

  1. 进阶Java编程(1)多线程编程

    Java多线程编程 1,进程与线程 在Java语言里面最大的特点是支持多线程的开发(也是为数不多支持多线程的编程语言Golang.Clojure方言.Elixir),所以在整个的Java技术学习里面, ...

  2. Java编程实现多线程TCP服务器完整实例

    Socket ·功能:TCP客户端套接字 ·构造方法:   Socket(InetAddress address, int port)   创建一个流套接字并将其连接到指定 IP 地址的指定端口号 · ...

  3. 黑马程序员:Java编程_多线程

    =========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== 进程:是一个正在执行中的程序.每一个进程执行都有一个执行顺序.该顺序是一个执行路 ...

  4. 进阶Java编程(13)反射与Annotation

    1,反射取得Annotation信息 从JDK1.5之后Java提供了Annotation技术支持,这种技术为项目的编写带来了新的模型,而后经过了十年的发展,Annotation的技术得到了非常广泛的 ...

  5. 进阶Java编程(10)反射与简单Java类

    1,传统属性自动赋值弊端 简单Java类主要由属性构成,并且提供有setter与getter类,同时简单Java类最大的特征就是通过对象保存相应的类属性的内容.但是如果使用传统的简单Java类开发,那 ...

  6. 进阶Java编程(5)基础类库

    Java基础类库 1,StringBuffer类 String类是在所有项目开发之中一定会使用到的一个功能类,并且这个类拥有如下的特点: ①每一个字符串的常量都属于一个String类的匿名对象,并且不 ...

  7. 进阶Java编程(3)线程的同步与死锁

    线程的同步与死锁 1,同步问题引出 在多线程的处理之中,可以利用Runnable描述多个线程操作的资源,而Thread描述每一个线程对象,对于当多个线程访问统一资源的时候如果处理不当就会产生数据的错误 ...

  8. 进阶Java编程(2)线程常用操作方法

    线程常用操作方法 多线程的主要操作方法都在Thread类中定义的. 1,线程的命名和取得 多线程的运行状态是不确定的,那么在程序的开发之中为了可以获取到一些需要使用到的线程就只能依靠线程的名字来进行操 ...

  9. 进阶Java编程(11)ClassLoader类加载器【待完成】

    1,ClassLoader类加载器简介 在Java里面提供一个系统的环境变量:ClassPath,这个属性的作用主要是在JVM进程启动的时候进行类加载路径的定义,在JVM里面可以根据类加载器而后进行指 ...

随机推荐

  1. L1-049 天梯赛座位分配 (20 分)

    L1-049 天梯赛座位分配 (20 分)(Java解法) 天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所 ...

  2. 火车购票问题(16年ccf)

    火车购票问题(16年ccf) 问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一节车厢有20排.每一排5个座位.为方便起见,我们用1到100来给所有的座位编号,第一 ...

  3. 解决ssh连接超时(ssh timeout)的方法

    echo export TMOUT=1000000 >> /root/.bash_profile (可设置为-1为永不超时) cat /root/.bash_profile source ...

  4. OriginPro 9.1 科研图标绘制入门

    OriginPro 9.1 科研图标绘制入门 目的:1.介绍如何不用编程画出复杂多样的图表2.介绍OriginLab 常用功能3.科研报告时,有效绘图,省却时间 科研发展需求.反映专业形象.满足公司要 ...

  5. Microsoft 防跨站点脚本库AntiXSS Library

    AntiXSS 库目前处于版本 4.2.1,下载地址:http://www.microsoft.com/download/en/details.aspx?id=28589.它经历了一次非常棒的重新编写 ...

  6. RDD的cache 与 checkpoint 的区别

    问题:cache 与 checkpoint 的区别? 关于这个问题,Tathagata Das 有一段回答: There is a significant difference between cac ...

  7. mybatis低版本jsr310(LocalDateTime,LocalDate等) Joda Time支持

    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybati ...

  8. iptable和tcpdump的先后顺序

    tcpdump是一个用来抓取linux网络数据包的工具,而iptables是linux上的防火墙工具,两者之间的顺序是: Wire -> NIC -> tcpdump -> netf ...

  9. Django之logging配置

    1. settings.py文件 做开发离不开必定离不开日志, 以下是我在工作中写Django项目常用的logging配置. # 日志配置 BASE_LOG_DIR = os.path.join(BA ...

  10. vue cli创建typescript项目

    使用最新的Vue CLI @vue/cli创建typescript项目,使用vue -V查看当前的vue cli版本 安装命令 npm install -g @vue-cli 创建项目 vue cre ...