Java多线程-synchronized关键字
进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。
一个进程中至少有一个线程
Java VM 启动的时候会有一个进程java.exe.该进程中至少一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。
扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程。
那么问题来了:
一、如何在自定义的代码中,自定义一个线程呢?
通过对api的查找,java已经提供了对线程这类事物的描述,就是Thread类。
Java中建立线程的方法有俩种:
1、通过某个类继承Thread类,并且重写run()方法来实现(不推荐)
2、通过某个类实现Runnable接口,并且重写run()方法 来实现
不推荐使用第一种的原因:Java是单继承的,如果某个类extends了Thread类,将不能再继承别的类,影响了代码的延展性。
俩种方法的区别:启动方法不同。
方法1:直接 线程名.start();即可启动线程。
方法2:先new一个对象,如:Test t=new Test(); //此时线程并没有被创建。
然后建立线程对象,并且将t放入其中, Thread td1=new Thread(t);
最后通过td1.start()来启动线程。
“方法2的启动方式其实就是将实现了Runnable接口的类的对象转换成标准的Thread类对象,然后再.start()来启动”
二、如果创建俩个线程,则会发现运行结果每一次都不同。
因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。明确一点,在某一个时刻,只能有一个程序在运行。(多核除外)cpu在做着快速的切换,以达到看上去是同时运行的效果。我们可以形象把多线程的运行行为在互相抢夺cpu的执行权。
这就是多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说的算。
三、为什么要覆盖run方法呢?
Thread类用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码。该存储功能就是run方法。也就是说Thread类中的run方法,用于存储线程要运行的代码。
java线程的同步--提出问题
多线程的并发,给我们编程带来很多好处,完成更多更有效率的程序。但是也给我们带来线程安全问题。
多线程的运行出现了安全问题。
问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,
另一个线程参与进来执行。导致共享数据的错误。
java线程的同步--解决问题
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。Java对于多线程的安全问题提供了专业的解决方式。
就是同步代码块。
synchronized(对象)
{
需要被同步的代码
}
关键就是要保证容易出问题的代码的原子性,所谓原子性就是指:当a线程在执行某段代码的时候,别的线程必须等到a线程执行完后,它才能执行这段代码。也就是排队一个一个解决。
对象如同锁。持有锁的线程可以在同步中执行。没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
同步的前提:
1,必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源,
售票案例演示
class Ticket implements Runnable
{
private int tick = 1000;
Object obj = new Object();
public void run()
{
while(true)
{
//同步锁,同步代码块
synchronized(obj)
{
if(tick>0)
{
//try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
}
}
}
}
} public class TestThread
{
public static void main(String[] args)
{ Ticket t = new Ticket(); Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start(); }
}
运行结果如下:由图可知,四个线程均在正常执行,并且实现了同步。
同步可以是一个同步代码块,也可以对一个函数进行同步,即使用同步函数。
*******注意*******
run()函数不可以被同步
*******注意*******
同步函数用的是哪一个锁呢?
函数需要被对象调用。那么函数都有一个所属对象引用。就是this。所以同步函数使用的锁是this。
如果同步函数被静态修饰后,使用的锁是什么呢? 通过验证,发现不在是this。因为静态方法中也不可以定义this。静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。类名.class 该对象的类型是Class 静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class
举例如下:
class Ticket implements Runnable
{
private static int tick = 100;
//Object obj = new Object();
boolean flag = true;
public void run()
{
if(flag)
{
while(true)
{
synchronized(Ticket.class)
{
if(tick>0)
{
try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
}
}
}
}
else
while(true)
show();
}
public static synchronized void show()
{
if(tick>0)
{
try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
}
}
} public class StaticMethodDemo
{
public static void main(String[] args)
{ Ticket t = new Ticket(); Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(10);}catch(Exception e){}
t.flag = false;
t2.start(); }
}
此例子中,使用了一个同步代码块和同步函数。分别在执行,俩者必须使用同一个锁才能保证现场安全。经测试,同步代码块中使用Ticket.class可以保证安全,所以静态同步函数中使用的锁即为:该方法所在类的字节码文件对象,类名.class
Java多线程-synchronized关键字的更多相关文章
- Java 多线程 —— synchronized关键字
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- Java多线程synchronized关键字
synchronized关键字代表着同步的意思,在Java中被synchronized修饰的有三种情况 1.同步代码块 //锁为objsynchronized(obj){ while(true){ i ...
- Java 多线程 - Synchronized关键字
目录 1-Synchronized 关键字概述 2- Synchronized关键字作用域 3- Synchronized 原理(反编译指令解释) 正文 1-Synchronized 关键字概述 由于 ...
- java多线程 synchronized关键字的一些用法
看这篇文章啦: http://blog.csdn.net/xiao__gui/article/details/8188833
- Java的synchronized关键字:同步机制总结
JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程 ...
- Java 多线程 - synchronize 关键字
目录 Java 多线程 - synchronize 关键字 Java 多线程 - synchronize 关键字 学习自 http://cmsblogs.com/?p=2071 https://www ...
- java基础Synchronized关键字之对象锁
java中Synchronized关键字之对象锁 当有多个线程对一个共享数据进行操作时,需要注意多线程的安全问题. 多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同 ...
- java中synchronized关键字分析
今天我们来分析一下java中synchronized关键字.首先来看一段java代码:(本地编译环境为mac,jdk1.8的环境) Demo.java package com.example.spri ...
- Java基础-synchronized关键字的用法(转载)
synchronized--同步 顾名思义是用于同步互斥的作用的. 这里精简的记一下它的使用方法以及意义: 当synchronized修饰 this或者非静态方法或者是一个实例的时候,所同步的锁是加在 ...
随机推荐
- 使用Robo 3T 软件管理MongoDB数据库如何执行命令行shell
比如使用命令行的方式查看数据库runoobdb中的sites集合(数据表)中的所有数据 1.在连接名的地方鼠标右键选择“open shell” 2.在出现的shell窗口中输入一下命令行,然后按ctr ...
- 弹层蒙版(mask),ios滚动穿透,我们项目的解决方案
问题描述 项目开发遇到一个ios独有的问题,在wkwebview中稳定复现 问题: 弹出一个蒙版,当在蒙版上面滑动的时候蒙版后面的内容滚动了 这当然是ios的bug,但是经过我们测试iphone7也会 ...
- JavaScript初步学习----基本使用,简单事件,修改样式,数据类型
JavaScript基本使用 JavaScript原名叫livescript,是一门动态类型,弱类型基于原型的脚本语言 用于页面特效,前后交替,后台开发(node) JavaScript写在s ...
- 【Codeforces 118B】Caesar's Legions
[链接] 我是链接,点我呀:) [题意] 序列中不能连续出现k1个以上的1以及不能连续出现k2个以上的2,然后一共有n1个1以及n2和2,要求这n1+n2个数字都出现. 问序列有多少种可能. [题解] ...
- How to change java version in Linux
How to change default Java version on Linux Posted on November 1, 2015 by Dan Nanni Leave a comment ...
- 百度地图API位置偏移的校准算法
转自极客人原文 百度地图API位置偏移的校准算法 在开始使用百度地图API进行开发时可能会遇到一件相当奇怪的事情,使用百度定位的经纬度在地图上显示相当不准确,这一问题我在微信开发和安卓开始时都遇到过. ...
- 开源GIS软件 2
Android上的导航软件 AndNav AndNav 是一款 Android 手机上的 GPS导航软件(非开源).软件支持GPS定位信息,目的地查询,道路建议管理,导航提示等功能,十分强大的一款软件 ...
- [MongoDB]安装 MongoDB 数据库
1.tar zxvf mongodb.tgz 2.vim ~/.bashrc 增加 MONGODB_HOME 并添加bin到PATH ,source ~/.bashrc 3.mongod -vers ...
- hibernate使用c3p0数据源
在配置好hibernate连接数据库环境的前提下,我们进行例如以下操作就能够搭建好hibernate中使用c3p0数据源的环境了. 1). 导入 jar 包: hibernate-release-4. ...
- java 执行可执行文件时提示“could not find or load main class ”的问题