发布网友 发布时间:2022-04-23 18:25
共2个回答
热心网友 时间:2023-10-12 21:08
Java实现单例的5种方式
1. 什么是单例模式
单例模式指的是在应用整个生命周期内只能存在一个实例。单例模式是一种被广泛使用的设计模式。他有很多好处,能够避免实例对象的重复创建,减少创建实例的系统开销,节省内存。
2. 单例模式和静态类的区别
首先理解一下什么是静态类,静态类就是一个类里面都是静态方法和静态field,构造器被private修饰,因此不能被实例化。Math类就是一个静态类。
知道了什么是静态类后,来说一下他们两者之间的区别:
1)首先单例模式会提供给你一个全局唯一的对象,静态类只是提供给你很多静态方法,这些方法不用创建对象,通过类就可以直接调用;
2)单例模式的灵活性更高,方法可以被override,因为静态类都是静态方法,所以不能被override;
3)如果是一个非常重的对象,单例模式可以懒加载,静态类就无法做到;
那么时候时候应该用静态类,什么时候应该用单例模式呢?首先如果你只是想使用一些工具方法,那么最好用静态类,静态类比单例类更快,因为静态的绑定是在编译期进行的。如果你要维护状态信息,或者访问资源时,应该选用单例模式。还可以这样说,当你需要面向对象的能力时(比如继承、多态)时,选用单例类,当你仅仅是提供一些方法时选用静态类。
热心网友 时间:2023-10-12 21:08
要实现单例,就需要知道目前进程的状态,如果存在,那么不允许同ID的process重复启动;
1.使用QSystemSemaphore lib;可在Create()失败时弹窗并退出ghost程序;
#include <QCoreApplication>
#include <QTextCodec>
#include <QSystemSemaphore>
#include <QSharedMemory>
#include <QMessageLogger>
#include "thread_datarecv.h"
#include "thread_datasend.h"
#include "com_config.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//设置程序使用字体,终端下显示可正常显示汉字
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
QSystemSemaphore sema("monkey",1,QSystemSemaphore::Open);
sema.acquire();
QSharedMemory mem("zhankong2");
if(mem.create(1)==false)
{
qDebug("本机已经运行一个实例,不能重复运行!");
sema.release();
//程序直接退出
//return a.exec();
exit(0);
}
sema.release();
initConfigFile();
Thread_DataRecv m_Thread_DataRecv;
Thread_DataSend m_Thread_DataSend;
QObject::connect(&m_Thread_DataRecv,SIGNAL(Send_procDatagrams(QByteArray)),&m_Thread_DataSend,SLOT(Slot_readGUIData(QByteArray)));
QObject::connect(&m_Thread_DataSend,SIGNAL(Send_DDatagrams(QByteArray)),&m_Thread_DataRecv,SLOT(Slot_readFDData(QByteArray)));
m_Thread_DataRecv.start();
m_Thread_DataSend.start();
return a.exec();
}
2.第二种是基于QLocalSocket监听,当ghost被创建时,会保持当前窗口和进程,并使ghost失效;
先看头文件:
#ifndef SINGLEEXECUTE_H
#define SINGLEEXECUTE_H
#include<QObject>
#include<QApplication>
/**
* @brief class SingleExecute
* @Author monulix
* 2018 05 25
*/
class QWidget;
class QLocalServer;
class SingleExecute: public QApplication{
Q_OBJECT
public:
SingleExecute(int &argc, char **argv);
bool isRunning();
QWidget* mainwindow;
private slots:
void newConnect();
private:
void initConnect(); //初始化
void newLocalServer(); //创建服务端
bool bRunning; //是否有实例运行
QLocalServer* localServer; //本地socket server
QString serverName; //服务名称
};
#endif // SINGLEEXECUTE_H
再看源文件:
#include "singleexecute.h"
#include <QWidget>
#include <QtNetwork/QLocalSocket>
#include <QtNetwork/QLocalServer>
#include <QFileInfo>
#include <QLibrary>
#include <qDebug>
/**
* @brief SingleExecute::SingleExecute
* @param argc
* @param argv
* @Author monulix
* 2018 05 25
*/
SingleExecute::SingleExecute(int &argc, char **argv)
:QApplication(argc, argv),
bRunning(false),
localServer(NULL),
mainwindow(NULL){
//应用名为localserver名;
serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
qDebug()<<serverName<<endl;
initConnect();
}
bool SingleExecute::isRunning(){
return bRunning;
}
/**
* use socket to complete exe single run, listen the new connection trig this func;
* add by lix; 2018 05 25;
*/
void SingleExecute::newConnect(){
QLocalSocket* socket = localServer->nextPendingConnection();
if(!socket)
return;
socket->waitForReadyRead(1000);
QTextStream stream(socket);
delete socket;
if(mainwindow != NULL){
mainwindow->raise();
mainwindow->activateWindow();
mainwindow->setWindowState((mainwindow->windowState() & Qt ::WindowMinimized) | Qt ::WindowActive);
mainwindow ->show();
}
}
void SingleExecute::initConnect(){
bRunning = false;
QLocalSocket socket;
socket.connectToServer(serverName);
if(socket.waitForConnected(500)){
bRunning = true;
QTextStream stream(&socket);
QStringList args = QCoreApplication::arguments();
if((args.count() > 1))
stream << args.last();
else
stream << QString();
stream.flush();
socket.waitForBytesWritten();
return;
}
newLocalServer();
}
void SingleExecute::newLocalServer(){
localServer = new QLocalServer(this);
/**
* @brief connect
* 2018 05 25; add by lix; deal new connection with reload slots;
*/
connect(localServer, SIGNAL(newConnection()),this,SLOT(newConnect()));
if(!localServer -> listen(serverName)){
//程序崩溃时,监听失败,残留进程服务导致(need remove thread)
if(localServer -> serverError() == QAbstractSocket:: AddressInUseError){
QLocalServer:: removeServer(serverName); //main point
localServer -> listen(serverName); //relisten;
}
}
}
最后在main()中的调用即可;
---------------------
作者:蒙娜丽轩
来源:CSDN
原文:https://blog.csdn.net/qq_32520245/article/details/80517117?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!
希望可以帮到你,谢谢!