JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止
JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止
一.生产者和消费者
什么是生产者和消费者?我们解释过来应该是生产一个,消费一个,的意思,具体我们通过例子来说
package com.lgl.hellojava; //公共的 类 类名 public class HelloJJAVA { public static void main(String[] args) { /** * 生产者和消费者 */ Resrource res = new Resrource(); Produce pro = new Produce(res); Consumer con = new Consumer(res); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); t1.start(); t2.start(); } } // 资源 class Resrource { private String name; private int count = 1; private boolean flag = false; // 生产 public synchronized void set(String name) { if (flag) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 每次设置添加编号 this.name = name + "-" + count++; System.out.println(Thread.currentThread().getName() + "--生产者--" + this.name); flag = true; this.notify(); } } // 消费 public synchronized void out() { if (!flag) try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "--消费者--" + this.name); flag = false; this.notify(); } } // 生产 class Produce implements Runnable { private Resrource res; public Produce(Resrource res) { this.res = res; } @Override public void run() { while (true) { System.out.println("Android"); } } } // 消费 class Consumer implements Runnable { private Resrource res; public Consumer(Resrource res) { this.res = res; } @Override public void run() { while (true) { res.out(); } } }
当我们生产一个,消费一个,就具有多线程的特性,如果出现其他现象,那就说明你的线程存在安全隐患了
二.停止线程
怎么让线程停?你会想到stop方法
既然已过时,我们就的去想其他办法了,跟其原理,是什么?run方法结束就是线程停止,那怎么让run方法结束?
- 只要控制循环,就可以让run方法结束,也就是线程的结束
我们写个实例
package com.lgl.hellojava; import org.omg.CORBA.FloatHolder; //公共的 类 类名 public class HelloJJAVA { public static void main(String[] args) { /** * 线程停止 */ stopThread s = new stopThread(); Thread t1 = new Thread(s); Thread t2 = new Thread(s); t1.start(); t2.start(); int num = 0; while (true) { if (num++ == 60) { s.changeFlag(); break; } else { System.out.println(Thread.currentThread().getName() + "Main run"); } } } } class stopThread implements Runnable { private boolean flag = true; @Override public void run() { while (flag) { System.out.println(Thread.currentThread().getName() + "Thread run"); } } public void changeFlag() { flag = false; } }
逻辑十分简单,只要达到要求,就停止,但是还有一种特殊情况,当线程处于冻结状态,就不会读取到标记,那线程就不会结束,我们看
package com.lgl.hellojava; import org.omg.CORBA.FloatHolder; //公共的 类 类名 public class HelloJJAVA { public static void main(String[] args) { /** * 线程停止 */ stopThread s = new stopThread(); Thread t1 = new Thread(s); Thread t2 = new Thread(s); t1.start(); t2.start(); int num = 0; while (true) { if (num++ == 60) { s.changeFlag(); break; } else { System.out.println(Thread.currentThread().getName() + "Main run"); } } } } class stopThread implements Runnable { private boolean flag = true; @Override public synchronized void run() { while (flag) { try { wait(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + "InterruptedException run"); } System.out.println(Thread.currentThread().getName() + "Thread run"); } } public void changeFlag() { flag = false; } }
这样就循环了。而在我们多线程中,提供了一个中断的方法Interupted
三.守护线程
守护线程其实也是Interupted中的东西,我们来看
你只要在启动线程前调用就可以了,就标记成了守护线程,就是一个依赖关系,你在我在,你不在我也不在;
四.Join方法
这个也是一个方法,意思是等待线程终止
我们倒是可以写个小例子
package com.lgl.hellojava; //公共的 类 类名 public class HelloJJAVA { public static void main(String[] args) { /** * Join */ Demo d = new Demo(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); try { // t1要申请加入到运行中来 t1.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t2.start(); for (int i = 0; i < 100; i++) { System.out.println("miam" + i); } System.out.println("main over"); } } class Demo implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "=---" + i); } } }
我们可以满足条件下 ,临时加入一个线程
当A线程执行到了B线程的join方法时,A线程就会等待,等B线程都执行完,A才会执行,A可以用来临时加入线程执行。
五.线程的优先级
线程有优先级,默认的优先级都是5,这个是可以改变的,t1.setPriority(优先级);
我们可以拿上面的例子来做个比较
package com.lgl.hellojava; //公共的 类 类名 public class HelloJJAVA { public static void main(String[] args) { /** * Join */ Demo d = new Demo(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); //权限虽然高,只是频率高而已 t1.setPriority(Thread.MAX_PRIORITY); t2.start(); for (int i = 0; i < 100; i++) { System.out.println("miam" + i); } System.out.println("main over"); } } class Demo implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "=---" + i); } } }
我们这里还有一个小方法yield,临时停止的意思,我们可以看例子
package com.lgl.hellojava; //公共的 类 类名 public class HelloJJAVA { public static void main(String[] args) { /** * Join */ Demo d = new Demo(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); t2.start(); for (int i = 0; i < 100; i++) { // System.out.println("miam" + i); } System.out.println("main over"); } } class Demo implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "=---" + i); Thread.yield(); } } }
我们可以看到
主线程并没有运行,那就对了,因为暂停了
我们到这里,本篇就结束了,同时线程所讲的知识也讲完了,线程博大精深,很值得我们学习,我所讲的,仍然只是一些皮毛罢了,希望大家多用心研究一下
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 一.静态同步函数的锁是class对象 我们在上节验证了同步函数的锁是this,但是对于静态同步函数,你又知道多少呢? 我们做一个这样的小实验,我们给show方法加上static关键字去修饰 private static synchronized void show() { if (tick > 0) { try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread() + "show:" + tick--); } } 然后我们来打印一下 发现他打印出0票了,说明他还是存在this隐患,同时也说明了一点就是他使用的锁不是this,那既然不是this,那是什么呢? 因为静态方法中,不可以定义this,...
- 下一篇
类加载及执行子系统的案例与实战
一、概述 在Class文件格式与执行引擎这部分中,Class文件以何种格式存储,类型何时加载、如何连接以及虚拟机如何执行字节码指令等都是由虚拟机直接控制行为,用户程序无法对其进行改变。能通过程序进行操作的,主要是字节码生成与类加载器这两部分。 二、案例分析 1、Tomcat:整体的类加载器架构 主流的java web服务器,如Tomcat、Jeety、WebLogic、WebSphere等都实现了自己定义的类加载器,因为他们需要解决一下问题: 1、部署在同一个服务器上的两个Web应用程序所使用的Java类库可以实现隔离(如不用应用程序依赖不同版本的第三方库) 2、部署在同一个服务器上的两个Web应用程序所使用的Java类库可以互相共享(如使用同一个Spring) 3、服务器需要尽可能保证自身的安全不受部署Web应用程序影响。 4、支持JSP应用的Web服务器大多需要支持HotSwap(热替换)功能,即JSP文件修改后无需重启 通过加装路径来解决上述问题 Tomcat目录结构中,有3组目录:/common/、/server/ 、/shared/ 可以存放Java类库,web应用程序自身的...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库