您的位置:首页 > 编程语言 > Java开发

线程同步与锁定_synchronized_单例模式_doubleCheckingJAVA178-179

2016-01-24 16:13 357 查看
来源:http://www.bjsxt.com/

一、S02E178_01线程同步与锁定1_synchronized

——由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。

——由于我们可以通过private关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是synchronized关键字,它包括两种用法:synchronized方法和synchronized块

——同步:并发,多个线程访问同一份资源(确保资源安全–>>线程安全)

1、同步块

——synchronized(引用类型或者this或者类.class){

}

2、同步方法

——synchronized

package com.test.thread.syn;

public class SynDemo {
public static void main(String[] args) {
//真实角色
Web12306 web = new Web12306();
//代理
Thread t1 = new Thread(web, "路人甲");
Thread t2 = new Thread(web, "黄牛乙");
Thread t3 = new Thread(web, "攻城狮");
t1.start();
t2.start();
t3.start();
}
}
class Web12306 implements Runnable {
private int num = 10;//1到10号
private boolean flag = true;
@Override
public void run(){
while(flag) {
//test1();
//test2();
//test3();
//test4();
//test5();
test6();
}
}
//线程不安全
public void test1(){
if(num <= 0){
flag = false;//跳出循环
return;
}
try {
Thread.sleep(500);//模拟延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
}
//同步方法,线程安全,锁定正确
public synchronized void test2(){
if(num <= 0){
flag = false;//跳出循环
return;
}
try {
Thread.sleep(500);//模拟延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
}
//同步块,线程安全,锁定正确
public void test3(){
synchronized(this){
if(num <= 0){
flag = false;//跳出循环
return;
}
try {
Thread.sleep(500);//模拟延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
}
}
//锁定范围不正确
public void test4(){
synchronized(this){
if(num <= 0){
flag = false;//跳出循环
return;
}
}
try {
Thread.sleep(500);//模拟延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
}
//线程不安全,锁定资源不正确
public void test5(){
synchronized((Integer)num){
if(num <= 0){
flag = false;//跳出循环
return;
}
try {
Thread.sleep(500);//模拟延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
}
}
//锁定范围不正确
public void test6(){
if(num <= 0){
flag = false;//跳出循环
return;
}
synchronized(this){
try {
Thread.sleep(500);//模拟延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
}
}
}


二、S02E179_01线程同步与锁定2_synchronized_单例模式_doubleChecking

package com.test.thread.syn;
/**
* 单例设计模式:外部使用时确保一个类只有一个对象(内部创建,外部不能创建,只能使用)
*/
public class Singleton {
public static void main(String[] args) {
JvmThread thread1 = new JvmThread(100);
JvmThread thread2 = new JvmThread(100);
thread1.start();
thread2.start();
}
}
class JvmThread extends Thread{
private long time;

public JvmThread(){
}
public JvmThread(long time){
this.time = time;
}
@Override
public void run(){
System.out.println(Thread.currentThread().getName()+"-->"+Jvm.getInstance(time));
}
}
/**
* 单例设计模式
* 外部使用时确保一个类只有一个对象(内部创建,外部不能创建,只能使用)
* 懒汉式  double checking
* 1、构造器私有化,避免外部直接创建对象
* 2、声明一个私有的静态变量
* 3、创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
*/
class Jvm{
//声明一个私有的静态变量
private static Jvm instance = null;//懒得创建对象

//构造器私有化,避免外部直接创建对象
private Jvm(){
}

//创建一个对外的公共的静态方法访问该变量,如果变量没有对象,创建该对象
//一、不同步,产生多个对象
public static Jvm getInstance1(long time){
if(null==instance){
try {
Thread.sleep(time);//延时,放大发生错误的概率
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Jvm();
}
return instance;
}
//二、加入synchronized,成为同步方法,只有一个对象
public static synchronized Jvm getInstance2(long time){
if(null==instance){
try {
Thread.sleep(time);//延时,放大发生错误的概率
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Jvm();
}
return instance;
}
//三、同步块,只有一个对象,效率不高,存在对象也需要等待
public static Jvm getInstance3(long time){
//a、b、c、d线程进来都需要等待,效率不高,存在对象也需要等待
synchronized(Jvm.class){//锁住类的字节码信息
if(null==instance){
try {
Thread.sleep(time);//延时,放大发生错误的概率
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Jvm();
}
return instance;
}
}
//四、同步块,只有一个对象,doubleChecking提高已经存在对象的访问效率
public static Jvm getInstance(long time){
//第二段:后来c、d线程都进来判断,发现有对象,直接返回,不用等待
if(null==instance){
//第一段:刚开始a、b线程都进来等待,a进入创建对象后,b再进入后发现有对象就直接返回
synchronized(Jvm.class){//锁住类的字节码信息
if(null==instance){
try {
Thread.sleep(time);//延时,放大发生错误的概率
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Jvm();
}
}
}
return instance;
}
}


package com.test.thread.syn;
/**
* 单例创建的方式
* 1、懒汉式
*  1)构造器私有化
*  2)声明私有的静态属性
*  3)对外提供访问属性的静态方法,确保该对象存在
*/
public class MyJvm {
private static MyJvm instance;
private MyJvm(){
}

public static MyJvm getInstance(){
if(null==instance){//提高效率
synchronized(MyJvm.class){
if(null==instance){//安全
instance = new MyJvm();
}
}
}
return instance;
}
}
/**
* 饿汉式
*  1)构造器私有化
*  2)声明私有的静态属性,同时创建该对象
*  3)对外提供访问属性的静态方法,确保该对象存在
*/
class MyJvm2 {
private static MyJvm2 instance = new MyJvm2();
private MyJvm2(){
}

public static MyJvm2 getInstance(){
return instance;
}
}
/**
* 类在使用时加载,延缓加载时机,提高效率
*/
class MyJvm3 {
private static class JvmHolder{//内部类,使用时加载
private static MyJvm3 instance = new MyJvm3();
}

private MyJvm3(){
}

public static MyJvm3 getInstance(){
return JvmHolder.instance;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: