সিম্পলডিটফর্ম্যাট অ্যাক্সেস সিঙ্ক্রোনাইজ করা


91

সিম্পলডিটফর্ম্যাট এর জাভাদোক বলে যে সিম্পলডেটফর্ম্যাটটি সিঙ্ক্রোনাইজ করা হয়নি।

"তারিখের ফর্ম্যাটগুলি সিঙ্ক্রোনাইজ করা হয় না each প্রতিটি থ্রেডের জন্য পৃথক ফর্ম্যাট উদাহরণ তৈরি করার পরামর্শ দেওয়া হয় multiple

তবে একাধিক থ্রেডযুক্ত পরিবেশে সিম্পলডেট ফরমেটের উদাহরণ ব্যবহার করার জন্য সর্বোত্তম পন্থাটি কী। এখানে আমি কয়েকটি বিকল্পের কথা ভেবেছি, আমি অতীতে 1 এবং 2 বিকল্পগুলি ব্যবহার করেছি তবে এর চেয়ে আরও ভাল বিকল্প আছে কি না বা এই বিকল্পগুলির মধ্যে কোনটি সেরা অভিনয় এবং সম্মতি প্রদান করবে তা জানতে আগ্রহী।

বিকল্প 1: যখন প্রয়োজন হয় স্থানীয় দৃষ্টান্ত তৈরি করুন

public String formatDate(Date d) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    return sdf.format(d);
}

বিকল্প 2: ক্লাস ভেরিয়েবল হিসাবে সিম্পলডেট ফরমেটের একটি উদাহরণ তৈরি করুন তবে এটিতে অ্যাক্সেসকে সিঙ্ক্রোনাইজ করুন।

private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public String formatDate(Date d) {
    synchronized(sdf) {
        return sdf.format(d);
    }
}

অপশন 3: প্রতিটি থ্রেডের জন্য সিম্পলডেট ফরমেটের ভিন্ন উদাহরণ সংরক্ষণ করার জন্য একটি থ্রেডলোকাল তৈরি করুন।

private ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();
public String formatDate(Date d) {
    SimpleDateFormat sdf = tl.get();
    if(sdf == null) {
        sdf = new SimpleDateFormat("yyyy-MM-hh");
        tl.set(sdf);
    }
    return sdf.format(d);
}

10
এই সমস্যা উত্থাপনের জন্য +1। তাই অনেকে মনে করেন যে সিম্পলডিটফর্ম্যাটটি থ্রেড নিরাপদ (আমি সর্বত্র অনুমান দেখি)।
অ্যাডাম জেন্ট

থ্রেডলোকাল পদ্ধতির সম্পর্কে আরও তথ্যের জন্য, দেখুন: javasp
विशेषज्ञ

: কেন জন্য, এই প্রশ্ন দেখতে পাবেন stackoverflow.com/questions/6840803/...
Raedwald

@ থারডোক আপনি কি অপশন -২ এ ভুলভাবে 'স্ট্যাটিক' কীওয়ার্ডটি এড়িয়ে গেছেন?
এম ফয়সাল হামেদ

উত্তর:


43
  1. সিম্পলডেট ফরমেট তৈরি করা ব্যয়বহুল । এটি খুব কমই সম্পন্ন না করা হলে এটি ব্যবহার করবেন না।

  2. ঠিক আছে যদি আপনি কিছুটা ব্লক করে বেঁচে থাকতে পারেন। ফর্ম্যাটডেট () বেশি ব্যবহার না করা থাকলে ব্যবহার করুন।

  3. দ্রুততম বিকল্প যদি আপনি থ্রেড পুনরায় ব্যবহার করেন ( থ্রেড পুল )। ২ এর চেয়ে বেশি মেমরি ব্যবহার করে এবং এর প্রারম্ভিক ওভারহেড বেশি।

অ্যাপ্লিকেশনগুলির জন্য 2 এবং 3 উভয়ই কার্যকর ব্যবহারযোগ্য বিকল্প। আপনার ক্ষেত্রে সবচেয়ে ভাল যা আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে। অকাল অপটিমাইজেশন থেকে সাবধান থাকুন। আপনি যদি বিশ্বাস করেন যে এটি কোনও সমস্যা।

3 য় পক্ষ দ্বারা ব্যবহৃত লাইব্রেরির জন্য আমি বিকল্প 3 ব্যবহার করব।


যদি আমরা বিকল্প 2 ব্যবহার করি এবং SimpleDateFormatউদাহরণের পরিবর্তনশীল হিসাবে ঘোষণা করি তবে আমরা synchronized blockএটিকে থ্রেড-নিরাপদ করতে ব্যবহার করতে পারি। তবে সোনার সতর্কতা স্কুইড-এএস 2885 দেখায় । সোনার সমস্যা সমাধানের কোনও উপায় আছে কি?
এম ফয়সাল হামেদ

24

অন্য বিকল্পটি হ'ল কমন্স ল্যাং ফাস্টডেটফর্ম্যাট তবে আপনি এটি কেবল তারিখ বিন্যাসের জন্য এবং পার্সিংয়ের জন্য ব্যবহার করতে পারেন।

জোদা থেকে ভিন্ন, এটি ফর্ম্যাটিংয়ের জন্য ড্রপ-ইন প্রতিস্থাপন হিসাবে কাজ করতে পারে। (আপডেট: v3.3.2 থেকে, ফাস্টডেটফর্ম্যাট একটি ফাস্টডেটপার্সার তৈরি করতে পারে , যা সিম্পলডেট ফরমেটের জন্য ড্রপ-ইন থ্রেড-নিরাপদ প্রতিস্থাপন)


8
কমন্স ল্যাঙ 3.2 সাল থেকে, FastDateFormatহয়েছে parse()পদ্ধতি হিসাবে ভাল
manuna

20

আপনি যদি জাভা 8 ব্যবহার করেন তবে আপনি ব্যবহার করতে পারেন java.time.format.DateTimeFormatter:

এই শ্রেণিটি অপরিবর্তনীয় এবং থ্রেড-নিরাপদ।

যেমন:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String str = new java.util.Date().toInstant()
                                 .atZone(ZoneId.systemDefault())
                                 .format(formatter);

6

কমন্স ল্যাং 3.x-এ এখন ফাস্টডেটপার্সারের পাশাপাশি ফাস্টডেটফর্ম্যাট রয়েছে। এটি থিম নিরাপদ এবং সিম্পলডেট ফরমেটের চেয়ে দ্রুত। এটি সরলডেটফরমেট হিসাবে একই বিন্যাস / পার্স প্যাটার্ন স্পেসিফিকেশন ব্যবহার করে।


এটি কেবলমাত্র 3.2+ এ উপলব্ধ এবং 3.x নয়
উইস্টেসো

4

সিম্পলডেটফরম্যাট ব্যবহার করবেন না, পরিবর্তে জোডা-টাইমের ডেটটাইমফর্ম্যাটর ব্যবহার করুন। এটি পার্সিং সাইডে কিছুটা কঠোর এবং তাই সিম্পলডেটফর্ম্যাটটির পরিবর্তে এটি খুব একটা ড্রপ নয়, তবে সুরক্ষা এবং পারফরম্যান্সের ক্ষেত্রে জোদা-সময়টি আরও একযোগে বন্ধুত্বপূর্ণ।


3

আমি বলব, সিম্পলডিটফর্ম্যাট এর জন্য একটি সাধারণ র‍্যাপার-ক্লাস তৈরি করুন যা পার্স () এবং ফর্ম্যাট () -এ অ্যাক্সেসকে সিঙ্ক্রোনাইজ করে এবং ড্রপ-ইন প্রতিস্থাপন হিসাবে ব্যবহার করা যেতে পারে। আপনার বিকল্প # 2 এর চেয়ে বেশি বোকা, আপনার বিকল্প # 3 এর চেয়ে কম জটিল।

দেখে মনে হচ্ছে যে সিম্পলডিটফর্ম্যাটটি আনসক্রোনাইজ করা জাভা এপিআই ডিজাইনারদের পক্ষে একটি দুর্বল নকশার সিদ্ধান্ত ছিল; আমি সন্দেহ করি যে কারও কাছে ফর্ম্যাট () এবং পার্স () সিঙ্ক্রোনাইজ করা দরকার exp


1

আর একটি বিকল্প হ'ল থ্রেড-নিরাপদ কাতারে দৃষ্টান্তগুলি রাখা:

import java.util.concurrent.ArrayBlockingQueue;
private static final int DATE_FORMAT_QUEUE_LEN = 4;
private static final String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
private ArrayBlockingQueue<SimpleDateFormat> dateFormatQueue = new ArrayBlockingQueue<SimpleDateFormat>(DATE_FORMAT_QUEUE_LEN);
// thread-safe date time formatting
public String format(Date date) {
    SimpleDateFormat fmt = dateFormatQueue.poll();
    if (fmt == null) {
        fmt = new SimpleDateFormat(DATE_PATTERN);
    }
    String text = fmt.format(date);
    dateFormatQueue.offer(fmt);
    return text;
}
public Date parse(String text) throws ParseException {
    SimpleDateFormat fmt = dateFormatQueue.poll();
    if (fmt == null) {
        fmt = new SimpleDateFormat(DATE_PATTERN);
    }
    Date date = null;
    try {
        date = fmt.parse(text);
    } finally {
        dateFormatQueue.offer(fmt);
    }
    return date;
}

ডেটফর্ম্যাট কিউয়ের আকারের আনুমানিক সংখ্যার থ্রেডের কাছাকাছি কিছু হওয়া উচিত যা নিয়মিতভাবে একই সময়ে এই ফাংশনটিকে কল করতে পারে। সবচেয়ে খারাপ ক্ষেত্রে যেখানে এই সংখ্যার চেয়ে বেশি থ্রেডগুলি প্রকৃতপক্ষে সমস্ত দৃষ্টান্ত ব্যবহার করে, কিছু সিম্পলডেটফর্ম্যাট দৃষ্টান্ত তৈরি করা হবে যা পূর্ণ ফর্মের কারণে তারিখের ফর্ম্যাটকিউতে ফিরানো যায় না। এটি কোনও ত্রুটি তৈরি করবে না, এটি কেবলমাত্র একবার ব্যবহার করা কিছু সিম্পলডেট ফর্ম্যাট তৈরির দন্ড বহন করবে।


1

আমি স্রেফ এটি অপশন 3 দিয়ে প্রয়োগ করেছি, তবে কয়েকটি কোড পরিবর্তন করেছি:

  • থ্রেডলোকাল সাধারণত স্থির হওয়া উচিত
  • ক্লিনারটিকে পরীক্ষার চেয়ে প্রারম্ভিক মূল্য () ওভাররাইড করতে মনে হয় ((() == নাল)
  • আপনি সত্যই ডিফল্ট সেটিংস না চাইলে আপনি লোকেল এবং টাইম জোন সেট করতে চাইতে পারেন (জাভা দিয়ে ডিফল্ট খুব ত্রুটিযুক্ত)

    private static final ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-hh", Locale.US);
            sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
            return sdf;
        }
    };
    public String formatDate(Date d) {
        return tl.get().format(d);
    }
    

0

আপনার অ্যাপ্লিকেশনটির একটি থ্রেড রয়েছে তা কল্পনা করুন। আপনি তখন সিম্পলডাটা ফর্ম্যাট ভেরিয়েবলের অ্যাক্সেসকে কেন সিঙ্ক্রোনাইজ করবেন?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.