最近忙着备考大学四年最后的两科,昨天刚考完大学所有的考试,但是大学专业是机械,但是自己热衷于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. 02-MySQL 介绍和安装

    MySQL 介绍和安装 1.什么是数据? 数据: 文字.图片.视频...人类认知的数据表现方式 计算机: 二进制.16进制的机器语言 基于数据的重要性和复杂性的不同,我们可能有不同的管理方式. 哪些数 ...

  2. SQLServer常用快捷键汇总

    菜单激活键盘快捷键 操作 SQL Server 2017 SQL Server 2008 R2 移到 SQL Server Management Studio 菜单栏 Alt Alt 激活工具组件的菜 ...

  3. 语义分析的waf 目前就看到长亭 机器学习的waf有fortnet 阿里云的waf也算

    近期,在全球权威咨询机构 Gartner 发布的 2019 Web 应用防火墙魔力象限中,阿里云 Web 应用防火墙成功入围,是亚太地区唯一一家进入该魔力象限的厂商! Web 应用防火墙,简称 WAF ...

  4. NOI.AC 722: tree

    就贴个代码 #include <cstdio> #include <algorithm> typedef long long LL; const int MN = 200005 ...

  5. Revit 2019 下载链接

    [安装环境]:win7/win8/win10 [64位下载] 百度网盘链接:pan.baidu.com/s/1Vq5Cnyj1G-oMNup_sXvxfQ  提取码:d6xd

  6. 数据呈现到 ASP.NET Core MVC 中展示

    终于要将数据呈现到 ASP.NET Core MVC 中的 视图 上了 将数据从控制器传递到视图的三种方法 在 ASP.NET Core MVC 中,有 3 种方法可以将数据从控制器传递到视图: 使用 ...

  7. ASP.NET Core 中的 Main 方法

    ASP.NET Core 中的 Main 方法 在 ASP.NET Core 项目中,我们有一个名为Program.cs的文件.在这个文件中,我们有一个public static void Main( ...

  8. 数据库的查——select的基本使用

    --创建学生表 create table students ( id int unsigned not null auto_increment primary key, name varchar(20 ...

  9. [LeetCode] 103. Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...

  10. javaSript 处理电脑和浏览器pc端缩放对页面的影响

    由于用户的个人习惯或其他原因,可能会调整到电脑上的缩放比例或者浏览器的缩放比例,如果访问页面会看起来比较不好看, 电脑上的缩放: 浏览器上的缩放: 解决方法: function detectZoom( ...