内容导航:

1、多线程的实现方式

2、线程安全问题

3、线程间通信

4、生产者消费者模式

第一部分多线程的实现方式

在java中多线程实现方式有2种

一、自定义一个类A,继承Thread类

 public class ThreadA extends Thread {
public void run(){ }
} }

此时ThreadA是一个线程类,在ThreadA中重写Thread类中的run方法

调用方式如下

ThreadA A = new ThreadA();
A.start();

二、自定义一个类B,实现Runable接口

 public class ThreadB implements Runnable {
public void run() { }
}

此时ThreadB不是一个线程类,在ThreadB中重写Thread类中的run方法

ThreadB b = new ThreadB();
Thread t1 = new Thread(b);
t1.start();

需要在初始化Thread的时候,把Runnable接口的实现类的对象b作为参数传入


第二部分是线程安全问题

线程安全问题产生的场景:

 public class SaleTickets implements Runnable {

     private int num = 100;   //表示100张火车票   这是共享资源

     //买100张火车票
public void run() {
for (int i = 0; i < num; i++) {
if (num > 0) {
System.out.println(Thread.currentThread().getName() + "买了编号为" + num + "的火车票");
num--;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
}
}
SaleTickets st=new SaleTickets ();
Thread tA=new Thread(st); //用户A
Thread tB=new Thread(st); //用户B tA.setName("用户A线程");
tB.setName("用户B线程"); tA.start();
tB.start();

进入12306购买火车票的时候,为了解决多个人同时进行抢票问题,需要使用多线程来增加系统效率,假如票共有100张,用户A和用户B同时进行买票,如果是单线程,每次用户买票的时候,首先会打印用户买到了哪张票,然后票的总数num减1。

但是由于是多线程,多线程有一个特性就是线程的执行顺序由cpu来分配,所以执行顺序是不确定的,假如用户A执行SaleTickets方法中的第10行的时候,会打印出用户A线程买了编号为100的火车票,此时用户B线程也开始执行SaleTickets方法,用户B也会打印出用户B线程买了编号为100的火车票

这种结果不是合理的,所以就引发线程安全问题

解决线程安全问题的方式有2种

1、同步代码块

 public class SaleTickets implements Runnable {

     private int num = 100;   //表示100张火车票   这是共享资源

     //买100张火车票
public void run() {
for (int i = 0; i < num; i++) {
synchronized (this){
if (num > 0) {
    System.out.println(Thread.currentThread().getName() + "买了编号为" + num + "的火车票");
    num--;
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    }
     }
}
}
}
}

2、同步方法

 public class SaleTickets implements Runnable {

     private int num = 100;   //表示100张火车票   这是共享资源

     public synchronized  void saleOne(){
if (num > 0) {
System.out.println(Thread.currentThread().getName() + "买了编号为" + num + "的火车票");
num--;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
} //买100张火车票
public void run() {
for (int i = 0; i < 10; i++) {
saleOne();
}
}
}

此时同步方法中的synchronized的锁默认为this


第三部分是线程间通信

线程间的通信机制为等待唤醒机制,多个线程通信的前提是共用同一把锁

wait(long  timeout) 当前线程释放锁,并等待timeout毫秒

notify 唤醒持有同一锁的某个线程

1、定义一个静态object对象,作为线程间通信的锁

 public class MyLock {
public static Object obj = new Object();
}

2、定义线程A

 //定义一个线程类  输出1
public class ThreadA extends Thread { public void run(){
for(int j=0;j<10;j++){
synchronized (MyLock.obj) {
System.out.println(1);
MyLock.obj.notify();
try {
MyLock.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} }

3、定义线程B

 //定义一个线程类   输出2
public class ThreadB extends Thread { public void run(){
for(int j=0;j<10;j++){
synchronized (MyLock.obj) {
System.out.println(2);
MyLock.obj.notify();
try {
MyLock.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} }

4、定义主函数执行线程A和线程B

 public class TestThreadForSignal {
public static void main(String[] args){
new ThreadA().start();
new ThreadB().start();
}
}

执行结果:交替打印1和2

执行原理:先执行线程A,会被同步代码块synchronized锁住,打印1,然后唤醒共用MyLock.obj锁的线程B,然后线程A进入等待,并释放锁。然后执行线程B,会被同步代码块synchronized锁住,打印2,然后唤醒共用MyLock.obj锁的线程A,然后线程B进入等待,并释放锁。接下来继续执行线程A循环往复.......


第四部分是生产者消费者模式

利用线程间通信可以很好的实现生产者消费者模式

因为这个代码跟上面线程通信的代码很类似,这里博主不打算继续码代码了,用文字做一个简要说明

线程A (农夫)  往篮子里放苹果   如果篮子满了(苹果数量=10),线程A wait,如果没满(苹果数量<10),往篮子里放苹果,同时告诉B(小孩儿) notify唤醒

线程B (小孩儿)从篮子里拿苹果吃   如果篮子空了(苹果数量=0),线程B wait   如果篮子里还有苹果(苹果数量>0),从篮子里拿苹果吃   同时告诉A(农夫)notify唤醒

在这个场景里线程A(农夫)是生产者,线程B(小孩儿)是消费者

Java基础篇---多线程的更多相关文章

  1. 金三银四跳槽季,BAT美团滴滴java面试大纲(带答案版)之一:Java基础篇

    Java基础篇: 题记:本系列文章,会尽量模拟面试现场对话情景, 用口语而非书面语 ,采用问答形式来展现.另外每一个问题都附上“延伸”,这部分内容是帮助小伙伴们更深的理解一些底层细节的补充,在面试中可 ...

  2. 小白—职场之Java基础篇

    java基础篇 java基础 目录 1.java是一种什么语言,jdk,jre,jvm三者的区别 2.java 1.5之后的三大版本 3.java跨平台及其原理 4.java 语言的特点 5.什么是字 ...

  3. java基础篇---I/O技术

    java基础篇---I/O技术   对于任何程序设计语言而言,输入输出(I/O)系统都是比较复杂的而且还是比较核心的.在java.io.包中提供了相关的API. java中流的概念划分 流的方向: 输 ...

  4. java基础篇---HTTP协议

    java基础篇---HTTP协议   HTTP协议一直是自己的薄弱点,也没抽太多时间去看这方面的内容,今天兴致来了就在网上搜了下关于http协议,发现有园友写了一篇非常好的博文,博文地址:(http: ...

  5. java基础篇---I/O技术(三)

    接上一篇java基础篇---I/O技术(二) Java对象的序列化和反序列化 什么叫对象的序列化和反序列化 要想完成对象的输入或输出,还必须依靠对象输出流(ObjectOutputStream)和对象 ...

  6. Java基础篇 - 强引用、弱引用、软引用和虚引用

    Java基础篇 - 强引用.弱引用.软引用和虚引用 原创零壹技术栈 最后发布于2018-09-09 08:58:21 阅读数 4936 收藏展开前言Java执行GC判断对象是否存活有两种方式其中一种是 ...

  7. java基础篇 之 构造器内部的多态行为

    java基础篇 之 构造器内部的多态行为 ​ 我们来看下下面这段代码: public class Main { public static void main(String[] args) { new ...

  8. java基础篇1

    JAVA基础篇1 注释 单行注释 //这是一个单行注释,由两个斜杠组成,不能嵌套多行注释 多行注释 /*这是一个 多行注释 ,//里面不能嵌套多行注释, 但是可以嵌套单行注释*/ 文档注释 /**ja ...

  9. Java基础篇(JVM)——类加载机制

    这是Java基础篇(JVM)的第二篇文章,紧接着上一篇字节码详解,这篇我们来详解Java的类加载机制,也就是如何把字节码代表的类信息加载进入内存中. 我们知道,不管是根据类新建对象,还是直接使用类变量 ...

随机推荐

  1. JQuery实践--插件

    jQuery插件的概览http://docs.jquery.com/Pluginshttp://jquery.com/plugins/most_popular 官方的表单插件http://jquery ...

  2. window、BOM、 document、 DOM

    window:  顾名思义,窗口,浏览器窗口.是Window构造函数的一个实例对象. 它包含浏览器的一些属性和方法,如screen,location,history,setInterval等. // ...

  3. learning express step(九)

    router-level middleware works in the same way as application-level middleware, except it is bound to ...

  4. P3979 遥远的国度 树剖

    P3979 遥远的国度 树剖 题面 需要想一下的树剖题,对于询问三需要处理换跟后的情况.我们以1为树根跑一遍剖分,对于换跟进行分类讨论,算出实际答案.讨论有三种情况: (以1为树根的树上) 跟在询问节 ...

  5. 学院管理系统(mysql版)

    需求 用户角色,讲师\学员, 用户登陆后根据角色不同,能做的事情不同,分别如下 讲师视图 管理班级,可创建班级,根据学员qq号把学员加入班级 可创建指定班级的上课纪录,注意一节上课纪录对应多条学员的上 ...

  6. slax linux的定制

    由于数据结构教学的需要,需要用到linux,要求就是小,启动快,可定制性强,恰好slax正好满足要求,以下就是定制slax linux的过程记录: 什么是Slax Slax是一个基于Linux的Liv ...

  7. JAVA基础知识|反射

    一.理解反射 1.1.基础概念 反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为ja ...

  8. WebService基础学习

    参考 WebService基础学习(一)—基础知识:http://www.cnblogs.com/yangang2013/p/5708647.html WebService基础学习(二)—三要素:ht ...

  9. 拆分项目搞成framework 实例

    目前工作中遇到的问题,是讲项目三大模块拆分, 将Discover.Shop和Events的源代码拆分到独立的项目中 拆分是个麻烦事,里面相互依赖很多 ,打包编译也异常复杂,各种报错 编译Event 遇 ...

  10. ArcGIS超级工具SPTOOLS-按属性裁剪,矢量数据批量裁剪,矢量数据批量合库

    1.1  按属性裁剪 操作视频: https://weibo.com/tv/v/HwaZRoosq?fid=1034:4376687438183117 按属性裁剪:可以图形表,也可以是非图形表,字段值 ...