当多线程去同时抢占CPU资源时,有多线程的安全问题。这时候就需要将线程同步。线程同步有俩个方法。

1.同步代码块(synchronize),同步代码块需要同步监视器,同步监视器是针对对象进行操作。什么对象时共享的,就可以给他加上同步监视器。

package com.bjsxt.ticker;

public class Ticket implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
synchronized (this) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
}
}
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }
package com.bjsxt.ticker;

public class TestTicket01 {
public static void main(String[] args) {
Ticket t=new Ticket(); Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口"); //启动线程
t1.start();
t2.start();
t3.start();
}
}

打印输出结果:

2.第二种就是同步方法:

package com.bjsxt.ticker;

public class Ticket1 implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
this.saleTicket();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } private synchronized void saleTicket() {//同步方法不需要指定同步监视器,同步监视器只能是当前对象this
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
}
} }
package com.bjsxt.ticker;

public class TestTicket01 {
public static void main(String[] args) {
Ticket1 t=new Ticket1(); Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口"); //启动线程
t1.start();
t2.start();
t3.start();
}
}

运行结果:

进行对比,我们将没有用线程同步的程序拿过来看看:

package com.bjsxt.ticker;

public class Ticket2 implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
if (ticket > 0) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
} } } }
package com.bjsxt.ticker;

public class TestTicket01 {
public static void main(String[] args) {
Ticket2 t=new Ticket2(); Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口"); //启动线程
t1.start();
t2.start();
t3.start();
}
}

运行结果:

可以看到,没有用同步方法,连0和-1都出来了,甚至还有俩个窗口卖同一张票的。这就是多线程没有用同步方法的线程安全。

最新文章

  1. 【.net 深呼吸】自定义缓存配置(非Web项目)
  2. 利用CSOM向列表添加文件夹
  3. Jquery对文本框的值、字符串的验证;正则表达式字符串的验证
  4. Script Form
  5. Python之路第八天,基础(9)-面向对象(下)
  6. oracle form 触发器执行顺序及键定义[Z]
  7. 使用命令创建github代码仓库,push本地仓库到github远程代码仓库
  8. Linux端图形处理工具ImageMagick在Centos上的安装
  9. IDEA 下新建 Hibernate 项目
  10. shell 批量修改较长字符串 字符串内容之间更换位置
  11. 数据库database
  12. java保留字
  13. Git分支merge和rebase的区别
  14. OpenCV图像分割2
  15. .net里Release的pdb文件有什么用 是否可以删除
  16. 使用bat文件执行sql文件
  17. 3. group_concat与oracle中wm_concat用法一样
  18. 弹性盒子 flexbox 元素居中
  19. ssh框架配置数据源 数据库连接没有正常释放
  20. ECCV 2014 Results (16 Jun, 2014) 结果已出

热门文章

  1. 你了解MySQL的加锁规则吗?
  2. css3 input placeholder颜色修改方法
  3. javascript JSMpeg.js 播放视频解决不用全屏也能播放(也支持自动播放哦)
  4. java VS c#,异同点
  5. python机器学习——逻辑回归
  6. python:collections模块
  7. Install Elastic stack
  8. cglib测试例子和源码详解
  9. devicemapper存储驱动下镜像的存储
  10. PostGIS mysql_fdw使用(Linux)