最近忙着备考大学四年最后的两科,昨天刚考完大学所有的考试,但是大学专业是机械,但是自己热衷于IT行业,想往IT行业走,希望毕业后能成功进入到IT行业,只希望毕业能找到一份Java开发工程师的工作,这样我才能专研和学习到更高深的技术.希望在毕业前能学到一点Java的精髓,让我可以成功进入到IT行业,加油~


线程问题:

 package demosummary.threadsafety;

 public class Ticket implements Runnable{
//定义票数
private int ticket = 100;
/**
* 执行卖票方法
*/
@Override
public void run() {
//卖票窗口永久开启
while (true) {
//判断票是否卖完
if (ticket > 0) {
try {
//三秒卖一张票
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println(name+"正在卖:"+ticket--);
}
}
}
} package demosummary.threadsafety; public class TicketTest {
public static void main(String[] args) {
//创建线程任务对象
Ticket ticket = new Ticket();
//创建三个窗口对象
Thread t1 = new Thread(ticket, "窗口1");
Thread t2 = new Thread(ticket, "窗口2");
Thread t3 = new Thread(ticket, "窗口3");
//启用窗口来卖票
t1.start();
t2.start();
t3.start();
}
/**
* 执行结果
* 窗口2正在卖:79
* 窗口3正在卖:79
* 窗口1正在卖:-1
* 出现重复卖同一张票和负票,在现实中是不允许出现的
*/
}

  注意:执行结果出现两种问题

    1.出现不同窗口卖同一张票,把票卖了两次

    2.出现卖不存在的票

  注意:这两种问题称为线程不安全

  线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写 操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步, 否则的话就可能影响线程安全

线程同步

  当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题。要解决上述多线程并发访问一个资源的安全性问题:也就是解决重复票与不存在票问题,Java中提供了同步机制 (synchronized)来解决

  方法:

    1. 同步代码块

    2. 同步方法

    3. 锁机制

同步代码块

  同步代码块: synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问

  格式:

    synchronized(同步锁){

      需要同步操作的代码

    }

  同步锁:对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁

    1. 锁对象 可以是任意类型。

    2. 多个线程对象  要使用同一把锁

  同步锁是谁?

    对于非static方法,同步锁就是this。

    对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。

  注意:在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着 (BLOCKED)

 package demosummary.threadsafety;

 public class Ticket02 implements Runnable {
//定义票数
private int ticket = 100; Object lock = new Object();
/**
* 执行卖票方法
*/
@Override public void run() {
//卖票窗口永久开启
while (true) {
synchronized (lock) {
//判断票是否卖完
if (ticket > 0) {
try {
//三秒卖一张票
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println(name + "正在卖:" + ticket--);
}
}
}
}
} package demosummary.threadsafety; public class TicketTest02 {
public static void main(String[] args) {
//创建线程任务对象
Ticket02 ticket = new Ticket02();
//创建三个窗口对象
Thread t1 = new Thread(ticket, "窗口1");
Thread t2 = new Thread(ticket, "窗口2");
Thread t3 = new Thread(ticket, "窗口3");
//启用窗口来卖票
t1.start();
t2.start();
t3.start();
}
}

  使用了同步代码块可以解决线程安全问题

同步方法

  同步方法:使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着。

  格式:

    public synchronized void method(){

      可能会产生线程安全问题的代码

    }

 package demosummary.threadsafety;

 public class Ticket03 implements Runnable {
private int ticket = 100; /**
* 执行卖票方法
*/
@Override
public void run() {
//卖票窗口永久开启
while (true) {
sellTicket();
}
} private synchronized void sellTicket() {
//判断票是否卖完
if (ticket > 0) {
try {
//三秒卖一张票
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//获取线程名称
String name = Thread.currentThread().getName();
System.out.println(name + "正在卖:" + ticket--);
}
}
} package demosummary.threadsafety; public class TicketTest03 {
public static void main(String[] args) {
//创建线程任务对象
Ticket03 ticket = new Ticket03();
//创建三个窗口对象
Thread t1 = new Thread(ticket, "窗口1");
Thread t2 = new Thread(ticket, "窗口2");
Thread t3 = new Thread(ticket, "窗口3");
//启用窗口来卖票
t1.start();
t2.start();
t3.start();
}
}

Lock锁

  java.util.concurrent.locks.Lock 机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作, 同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象

  Lock锁也称同步锁,加锁与释放锁方法化了,如下

    public void lock() :加同步锁。

    public void unlock() :释放同步

 package demosummary.threadsafety;

 import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Ticket04 implements Runnable {
//定义票数
private int ticket = 100; //创建锁对象
Lock lock = new ReentrantLock();
/**
* 执行卖票方法
*/
@Override
public void run() {
//卖票窗口永久开启
while (true) {
//给线程加锁
lock.lock();
//判断是否邮票可卖
if (ticket > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//获取线程当前名称
String name = Thread.currentThread().getName();
System.out.println(name+"正在卖"+ticket--);
}
//释放线程锁
lock.unlock();
}
}
} package demosummary.threadsafety; public class TicketTest04 {
public static void main(String[] args) {
//创建线程任务对象
Ticket04 ticket = new Ticket04();
//创建三个窗口对象
Thread t1 = new Thread(ticket, "窗口1");
Thread t2 = new Thread(ticket, "窗口2");
Thread t3 = new Thread(ticket, "窗口3");
//启用窗口来卖票
t1.start();
t2.start();
t3.start();
}
}

线程安全---Day23的更多相关文章

  1. 老男孩python学习自修第二十三天【多线程】

    1. 线程的创建与运行 #!/usr/bin/env python # _*_ coding:UTF-8 _*_ from threading import Thread def foo(param1 ...

  2. 黑马程序员_Java基础视频-深入浅出精华版--视频列表

    \day01\avi\01.01_计算机基础(计算机概述).avi; \day01\avi\01.02_计算机基础(计算机硬件和软件概述).avi; \day01\avi\01.03_计算机基础(软件 ...

  3. 课程2:《黑马程序员_Java基础视频-深入浅出精华版》-视频列表-

    \day01\avi\01.01_计算机基础(计算机概述).avi; \day01\avi\01.02_计算机基础(计算机硬件和软件概述).avi; \day01\avi\01.03_计算机基础(软件 ...

  4. Pyhton学习——Day23

    #re模块方法:findall search#findall:返回所有满足匹配条件的数值,放在列表里#search : #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象 ...

  5. javasE--基础部分--线程

    Day23 本单元目标 一.线程的相关概念  二.线程的创建和启动★ 三.线程的停止 四.线程的常用方法 五.线程的生命周期★  六.线程的同步 七.线程的通信 八.线程的创建方式三 九.线程的创建方 ...

  6. Java第二十四天,线程安全

    线程安全 1.定义 多线程访问共享数据,会产生线程安全问题. 2.代码模拟 卖票Ticked类: package com.lanyue.day22; public class Person { pub ...

  7. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  8. [高并发]Java高并发编程系列开山篇--线程实现

    Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...

  9. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

随机推荐

  1. 16、基于状态的iptable+高级路由(重点)

    --   基于状态的iptables   如果按照tcp/ip来划分连接状态,有12种之多 但iptables里只有4种状态:ESTABLISHED.NEW.RELATED及INVALID   这两个 ...

  2. python3 AES 加解密

    #coding:utf-8 import base64 from Crypto.Cipher import AES #注:python3 安装 Crypto 是 pip3 install -i htt ...

  3. flask 上下文

    上文:找到被创建成字典形式的东西 下文: 找到request并执行

  4. 微信小程序,知识点

    对于小程序的授权,只要用户授权一次,该授权关系就会记录在后台,除非删除小程序,或者用户在设置中关闭该授权. 官方文档: https://developers.weixin.qq.com/minipro ...

  5. 常用开窗函数总结(hive、sparkSQL可执行)

    一:根据某个字段排序 测试数据: SQL> select * from sscore; NAME       SCORE ---------- ----- aa            99 bb ...

  6. Spring Data介绍

    Spring Data是Spring 的一个子项目.用于简化数据库访问,支持NoSQL和关系数据库存储.其主要目标是使数据库的访问变得方便快捷. Spring Data 项目所支持NoSQL存储: M ...

  7. NOIP 2016 回文日期

    洛谷P2010 https://www.luogu.org/problemnew/show/P2010 JDOJ 3313 https://neooj.com:8082/oldoj/problem.p ...

  8. HTTP几种认证方式介绍

    HTTP提供了一套标准的身份验证框架:服务器可以用来针对客户端的请求发送质询(challenge),客户端根据质询提供身份验证凭证.质询与应答的工作流程如下:服务器端向客户端返回401(Unautho ...

  9. python中多线程相关

    基础知识 进程:进程就是一个程序在一个数据集上的一次动态执行过程 数据集:程序执行过程中需要的资源 进程控制块:完成状态保存的单元 线程:线程是寄托在进程之上,为了提高系统的并发性 线程是进程的实体 ...

  10. HDU 4005 The war(边双连通)

    题意 ​ 给定一张 \(n\) 个点 \(m\) 条边的无向连通图,加入一条边,使得图中权值最小的桥权值最大,如果能使图中没有桥则输出 \(-1\). 思路 ​ 先对原图边双缩点,然后变成了一棵树.在 ...