java怎么实现单实例运行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java怎么实现单实例运行相关的知识,希望对你有一定的参考价值。

Java实现单例的5种方式
1. 什么是单例模式
单例模式指的是在应用整个生命周期内只能存在一个实例。单例模式是一种被广泛使用的设计模式。他有很多好处,能够避免实例对象的重复创建,减少创建实例的系统开销,节省内存。
2. 单例模式和静态类的区别
首先理解一下什么是静态类,静态类就是一个类里面都是静态方法和静态field,构造器被private修饰,因此不能被实例化。Math类就是一个静态类。
知道了什么是静态类后,来说一下他们两者之间的区别:
1)首先单例模式会提供给你一个全局唯一的对象,静态类只是提供给你很多静态方法,这些方法不用创建对象,通过类就可以直接调用;
2)单例模式的灵活性更高,方法可以被override,因为静态类都是静态方法,所以不能被override;
3)如果是一个非常重的对象,单例模式可以懒加载,静态类就无法做到;
那么时候时候应该用静态类,什么时候应该用单例模式呢?首先如果你只是想使用一些工具方法,那么最好用静态类,静态类比单例类更快,因为静态的绑定是在编译期进行的。如果你要维护状态信息,或者访问资源时,应该选用单例模式。还可以这样说,当你需要面向对象的能力时(比如继承、多态)时,选用单例类,当你仅仅是提供一些方法时选用静态类。
参考技术A 要实现单例,就需要知道目前进程的状态,如果存在,那么不允许同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
版权声明:本文为博主原创文章,转载请附上博文链接!
希望可以帮到你,谢谢!

Java单例模式 多种实现方式

一:通过静态私有成员实现单例模式

(1):私有化构造函数

(2):new静态实例属性对象,加锁。

单例类:

package SinglePag;
/*
 * 构造函数私有化,结合锁+静态的概念 实现单例模式
 */
public class SingleDemo {
    //防止类的实例化
    private SingleDemo(){
        
    }
    //静态 实例 属性
    private static SingleDemo singleD;
    //获取对象实例 (单例的方式 ),锁住当前类(加锁)
    
    public synchronized static SingleDemo getInstance(){
        if(singleD == null){
            singleD = new SingleDemo();
        }
        return singleD;
    }
}

实现:

package SinglePag;

public class SingleWinform {
    public static void main(String[] args) {
        SingleDemo singleDemo = SingleDemo.getInstance();
        System.out.println(singleDemo.hashCode());
        SingleDemo singleDemo2 = SingleDemo.getInstance();
        System.out.println(singleDemo2.hashCode());
    }
}


二:静态内部类实现单例模式

(1):私有化构造函数

(2):私有静态内部类,创建静态实例成员对象

(3):静态实例获取方法

单例类:

package SinglePag;

public class SingleInnerStatic {
    //静态内置类
    private static class InnerStatic{
        //静态私有 实例属性
        private static SingleInnerStatic singleInstance;
        static{
            singleInstance = new SingleInnerStatic();
        }
    }
    
    //私有化构造函数,防止实例化
    private SingleInnerStatic(){
        
    }
    
    public static SingleInnerStatic getInstance(){
        return InnerStatic.singleInstance;
    }
}

实现:

package SinglePag;

public class SingleStaticWinform {
   public static void main(String[] args) {
       SingleInnerStatic singleInnerStatic =SingleInnerStatic.getInstance();
       System.out.println(singleInnerStatic.hashCode());
       
       SingleInnerStatic singleInnerStatic2 = SingleInnerStatic.getInstance();
       System.out.println(singleInnerStatic2.hashCode());
   }
}

 


以上是关于java怎么实现单实例运行的主要内容,如果未能解决你的问题,请参考以下文章

单实例应用程序

js设计模式之单例模式实例

双重检查锁实现单例(java)

spring怎么实现单例模式?

Linux - 通过操作文件锁来实现shell script进程单实例

Java设计模式之:单例模式