Java——单例模式、多线程
单例模式
单例模式是一种常用的软件设计模式。
在它的核心结构中只包含一个被成为单例类的特殊类。通过单例模式可以保证系统中一个类职业一个实例而且该实例易于外界访问,从而方面对实例个数的控制并节约系统资源。
如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
单例模式练习
public class Person {
private int id;
//单例模式:整个系统共享一个对象
public Person(int id) {
super();
this.id = id;
}
//测试
public static void main(String[] args) {
Person p1 = new Person(1);
Person p2 = new Person(2);
}
public void test(){
Singleton ton = Singleton.getInstance();
System.out.println(ton.hashCode());
}
}
单例模式的分类
懒汉式
优点:只有调用方法才创建对象,调用之前不会占用内存
缺点:在多线程模式下不安全
懒汉式相关练习:
public class Singleton {
//私有化构造,只有在本类之中才可以new出来。超出本类无法访问
private Singleton(){
}
//全局对象
private static Singleton singleton=null;
//synchronized 如果加上关键字,则一样
// synchronized 如果没有该关键字,则创建了两个线程不同步
//synchronized 它的位置决定了锁的范围
public static synchronized Singleton getInstance(){
//判断全局对象是否为空
if(singleton==null){
try {
//休眠一秒钟
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//如果为空,就创建该类对象
singleton=new Singleton();
}
//如果不为空,就直接返回该对象
return singleton;
}
public static void main(String[] args) {
//多线程操作
//2.直接使用Thread操作
Thread thread = new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
Singleton ton = Singleton.getInstance();
System.out.println(ton.hashCode());
}
};
thread.start();
Thread thread2 = new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
Singleton ton2 = Singleton.getInstance();
System.out.println(ton2.hashCode());
}
};
//开启新线程
thread2.start();
// Person p = new Person(0);
// p.test();
// Singleton s = new Singleton();
// System.out.println(s.hashCode());
}
}
饿汉式
跟懒汉式的区别,直接创建对象。
饿汉式不管有没有调用getInstance方法,都会预先在系统中创建一个静态对象
懒汉式不会预先创建对象,只有在第一次调用时才创建对象。
优点:在多线程模式下是安全的
- 缺点:没有调用方法前就加载,会占用系统内存。
饿汉式相关练习:
public class Singleton2 {
//跟懒汉式的区别,直接创建对象
private static Singleton2 ton = new Singleton2();
//私有构造
private Singleton2(){
System.out.println("对象创建成功!");
}
public static Singleton2 getInstance(){
return ton;
}
/**
* 饿汉式不管有没有调用getInstance方法,
* 都会预先在系统中创建一个静态对象。
* 懒汉式不会预先创建对象,只有在第一次调用时,
* 才创建对象。
* 饿汉式
* 优点:在多线程模式下是安全的。
* 缺点:没有调用方法前就加载,会占用系统内存。
* @param args
*/
public static void main(String[] args) {
Singleton2 ton = Singleton2.getInstance();
System.out.println(ton.hashCode());
}
}
线程安全
饿汉式本身就是线程安全的,可以直接用于多线程而不会出现问题的。
懒汉式是非线程安全的,解决方式如下:
关键字:synchronized:可以用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。
使用双重检测机制实现线程安全的懒汉式
使用静态内部类实现线程安全的单例模式
多线程
public class Ch01 {
/**
* 系统默认情况下只运行主线程
* @param args
*
public static void main(String[] args) {
//主线程中开启两个子线程
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();
thread1.start();
thread2.start();
}
}
/**
* 多线程类1
* @author alery
*
*/
class Thread1 extends Thread{
/**
* 线程运行期间执行的代码
*/
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("线程1开始运行。。。。。");
//休眠1秒钟
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("线程1 继续执行......");
}
}
/**
* 多线程类2
*/
class Thread2 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("线程2开始运行。。。。。");
//休眠1秒钟
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("线程2 继续执行......");
}
}
多线程的三种方式
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
/**
* JAVA三种方式实现多线程
* @author Administrator
*
*/
public class ThreadTest implements Runnable,Callable<String>{
public static void main(String[] args) throws InterruptedException, ExecutionException {
// TODO Auto-generated method stub
//主线程打印
// System.out.println("线程编号:"+Thread.currentThread().getId());
// new ThreadA().start();
// Thread thread=new Thread(){
// public void run() {
// System.out.println(Thread.currentThread().getId()+"线程正在运行");
// }
// };
// thread.start();
ThreadTest t=new ThreadTest();
// new Thread(t).start();
// new Thread(new Runnable() {
//
// @Override
// public void run() {
// // TODO Auto-generated method stub
// System.out.println(Thread.currentThread().getId()+"线程正在运行");
// }
// }).start();
//Runnable
// FutureTask<String> task=new FutureTask<String>(t);
// new Thread(task).start();
// //获取call方法返回的内容
// System.out.println(task.get());
//线程池内线程最大数量
int threadMaxCount=10;
//线程池
ExecutorService service=Executors.newFixedThreadPool(threadMaxCount);
//定义一个集合存储runnable
List<Future<String>> list=new ArrayList<Future<String>>();
//开始运行10个线程(这10个多线程是由线程池管理的)
for(int i=0;i<threadMaxCount;i++) {
FutureTask<String> task=new FutureTask<String>(t);
//submit把runnable提交给了线程池
Future<String> f=(Future<String>) service.submit(task);
list.add(task);
}
// service.shutdown();
for(int i=0;i<list.size();i++) {
Future<String> f=list.get(i);
System.out.println(f.get());
}
}
/**
* 2.实现Runnable接口
* 必须重写run方法
* 创建Thread对象,把runnable传递到构造中
* (匿名实现类)
*/
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getId()+"线程正在运行");
}
/**
* 3.实现Callable接口
* 重写call方法
* 使用FutureTask类来实现Runnable
* (FutureTask是Runnable的实现类)
* 创建Thread对象,把FutureTask当作Runnable调用了构造参数
* call方法的返回值可以通过FutureTask.get方法得到
* (get方法必须在线程运行之后才可以调用)
* 线程池配合使用比较好
*/
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
String str=Thread.currentThread().getId()+"线程正在运行";
// System.out.println(str);
return str;
}
}
/**
* 1.继承Thread类
* 重写run方法
* (匿名类方式实现)
* @author Administrator
*
*/
class ThreadA extends Thread{
/**
* 当线程start时,会执行run
*/
@Override
public void run() {
// super.run();
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getId()+"线程正在运行");
}
}
Java——单例模式、多线程的更多相关文章
- 【深入】java 单例模式(转)
[深入]java 单例模式 关于单例模式的文章,其实网上早就已经泛滥了.但一个小小的单例,里面却是有着许多的变化.网上的文章大多也是提到了其中的一个或几个点,很少有比较全面且脉络清晰的文章,于是,我便 ...
- 深入Java单例模式(转)
深入Java单例模式 源自 http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容 ...
- Java基础-多线程-②多线程安全问题
什么是线程的安全问题? 上一篇 Java基础-多线程-①线程的创建和启动 我们说使用实现Runnable接口的方式来创建线程,可以实现多个线程共享资源: class Dog implements Ru ...
- Java 单例模式的七种写法
Java 单例模式的七种写法 第一种(懒汉,线程不安全) public class Singleton { private static Singleton instance; private Sin ...
- java单例模式之懒汉式分析
转自:http://blog.csdn.net/withiter/article/details/8140338 今天中午闲着没事,就随便写点关于Java单例模式的.其实单例模式实现有很多方法,这里我 ...
- Java 单例模式探讨
以下是我再次研究单例(Java 单例模式缺点)时在网上收集的资料,相信你们看完就对单例完全掌握了 Java单例模式应该是看起来以及用起来简单的一种设计模式,但是就实现方式以及原理来说,也并不浅显哦. ...
- 单例模式:Java单例模式的几种写法及它们的优缺点
总结下Java单例模式的几种写法: 1. 饿汉式 public class Singleton { private static Singleton instance = new Singleton( ...
- 9种Java单例模式详解(推荐)
单例模式的特点 一个类只允许产生一个实例化对象. 单例类构造方法私有化,不允许外部创建对象. 单例类向外提供静态方法,调用方法返回内部创建的实例化对象. 懒汉式(线程不安全) 其主要表现在单例类在外 ...
- 你真的理解了java单例模式吗?讲别人都忽略的细节!
前言:老刘这篇文章敢做保证,java的单例模式讲的比大多数的技术博客都要好,讲述别人技术博客都没有的细节!!! 1 java单例模式 直接讲实现单例模式的两种方法:懒汉式和饿汉式,单例模式的概念自己上 ...
随机推荐
- 第二章 进程同步(二)——> 重点
2.4 进程同步 2.4.1 进程同步的基本概念 1. 两种形式的制约关系 (1)间接相互制约关系:互斥问题(往往是互斥设备)---是同步的特例 (2)直接相互制约关系:同步问题 注: 互斥问题 ...
- ARM CPU的SVC模式
关于ARM CPU模式中的SVC Arm中CPU的模式 [第一方面] 系统sys模式 VS 管理svc模式 首先,sys模式和usr模式相比,所用的寄存器组,都是一样的,但是增加了一些访问一些在usr ...
- JS 字符串比较"=="与"==="区别
最近课程油js的课程,课后习题有道关于下面 1 类似的一道题,叫比较然后判断结果,最开始看了网上的知识点,还是有点不太懂,个人感觉模模糊糊的(当然我自己菜,是正常的),就用依稀还记得的java对象与引 ...
- 阿里云centos7[linux]安装nginx
标题 说明 服务器版本 Centos7 x64 nginx版本 1.19.6 作者 walton 一.准备 创建安装包目录并进入 mkdir /usr/dev/nginx cd /usr/dev/ng ...
- WebSocket协议中文版
WebSocket协议中文版 摘要 WebSocket协议实现在受控环境中运行不受信任代码的一个客户端到一个从该代码已经选择加入通信的远程主机之间的全双工通信.用于这个安全模型是通常由web浏览器使用 ...
- C#处理医学图像(二):基于Hessian矩阵的医学图像增强与窗宽窗位
根据本系列教程文章上一篇说到,在完成C++和Opencv对Hessian矩阵滤波算法的实现和封装后, 再由C#调用C++ 的DLL,(参考:C#处理医学图像(一):基于Hessian矩阵的血管肺纹理骨 ...
- 【JavaWeb】AJAX 请求
AJAX 请求 什么是 AJAX AJAX(Asynchronous JavaScript And XMl),即异步 JS 和 XML.是指一种创建交互式网页应用的网页开发技术. AJAX 是一种浏览 ...
- 关于软件架构中的b/s
**B/S架构 b/s只需要一个浏览器,用户就可以通过不同的网址访问不同的服务器程序. 优点:开发,安装,部署,维护简单 缺点:对硬件要求过高,用户的体验会受到影响 首先是资源分类:**可以分为静态资 ...
- SpringBoot对静态资源的映射规则
在WebMvcAutoConfiguration类中有相对应的方法addResourceHandlers public void addResourceHandlers(ResourceHandler ...
- [mysql]ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value
转载自:http://www.cnblogs.com/joeblackzqq/p/4526589.html From: http://m.blog.csdn.net/blog/langkeziju/1 ...