জাভা রেজেক্স থ্রেড কি নিরাপদ?


104

আমার একটি ফাংশন রয়েছে যা ব্যবহার করে Pattern#compileএবং Matcherএকটি প্যাটার্নের জন্য স্ট্রিংগুলির তালিকা অনুসন্ধান করতে।

এই ফাংশনটি একাধিক থ্রেডে ব্যবহৃত হয়। প্রতিটি থ্রেডের একটি অনন্য প্যাটার্ন থাকবে Pattern#compileযখন থ্রেডটি তৈরি করা হবে। থ্রেড এবং নিদর্শনগুলির সংখ্যা গতিশীল, যার অর্থ Patternকনফিগারেশনের সময় আমি আরও গুলি এবং থ্রেড যুক্ত করতে পারি ।

আমি synchronizeযদি এই ক্রিয়াকলাপটি ব্যবহার করে তবে এই ফাংশনটিতে আমার কী লাগবে? জাভা থ্রেডে রিজেক্স কি নিরাপদ?

উত্তর:


132

হ্যাঁ , প্যাটার্ন ক্লাসের জন্য জাভা এপিআই ডকুমেন্টেশন থেকে

এই (প্যাটার্ন) শ্রেণির উদাহরণগুলি অপরিবর্তনীয় এবং একাধিক সমবর্তী থ্রেড দ্বারা ব্যবহারের জন্য নিরাপদ। ম্যাচার ক্লাসের উদাহরণগুলি এ জাতীয় ব্যবহারের জন্য নিরাপদ নয়।

আপনি যদি পারফরমেন্স কেন্দ্রিক কোডের দিকে তাকিয়ে থাকেন তবে নতুন দৃষ্টান্ত তৈরির পরিবর্তে পুনরায় সেট করুন () পদ্ধতিটি ব্যবহার করে ম্যাচার দৃষ্টান্তটি পুনরায় সেট করার চেষ্টা করুন। এটি ম্যাচারের দৃষ্টান্তটি পুনরায় সেট করবে এবং পরবর্তী রেজেক্স অপারেশনের জন্য এটি ব্যবহারযোগ্য করে তুলবে। প্রকৃতপক্ষে, এটি ম্যাচারের ক্ষেত্রে রক্ষণাবেক্ষণ করা রাজ্য যা একই সাথে অ্যাক্সেসের জন্য অনিরাপদ হওয়ার জন্য দায়ী।


17
প্যাটার্ন অবজেক্টস থ্রেড নিরাপদ, কিন্তু compile()পদ্ধতি নাও হতে পারে। বহু বছর ধরে দুটি বা তিনটি বাগ রয়েছে যার ফলে বহুবিবাহিত পরিবেশে সংকলন ব্যর্থ হয়েছে। আমি একটি সিঙ্ক্রোনাইজড ব্লকে সংকলন করার পরামর্শ দেব।
অ্যালান মুর

4
হ্যাঁ, প্যাটার্ন ক্লাসে একযোগে বাগ উত্থাপিত হয়েছে এবং সিঙ্ক্রোনাইজ অ্যাক্সেসের আপনার পরামর্শকে প্রশংসা করা হয়েছে। তবে প্যাটার্ন ক্লাসের মূল বিকাশকারীরা প্যাটার্ন ক্লাসটিকে থ্রেড হিসাবে সুরক্ষিত করার লক্ষ্যে কাজ করেছিল এবং যে চুক্তিটি ছিল যে কোনও জাভা প্রোগ্রামার নির্ভর করতে সক্ষম হবে। প্রকৃতপক্ষে, আমি থ্রেড স্থানীয় ভেরিয়েবলগুলি পেয়েছি এবং চুক্তির মাধ্যমে থ্রেড নিরাপদ আচরণের উপর নির্ভর করার চেয়ে ন্যূনতম পারফরম্যান্স হিট গ্রহণ করব (যদি না আমি কোডটি দেখেছি)। তারা যেমন বলে "থ্রেডিং সহজ, সঠিক সিঙ্ক্রোনাইজেশন শক্ত" "
ভিনিতে রেনল্ডস

1
নোট করুন যে "প্যাটার্ন" এর উত্সটি ওরাকল জেডিকে বিতরণে রয়েছে ( oracle.com/technetwork/java/faq-141681.html#A14 অনুসারে : "জাভা 2 এসডিকে, স্ট্যান্ডার্ড সংস্করণে নিজেই একটি ফাইল রয়েছে যা এসআরসি.জিপ বলে জাভা প্যাকেজটিতে সর্বজনীন ক্লাসের উত্স কোড রয়েছে ") যাতে কেউ দ্রুত উঁকি নিতে পারে।
ডেভিড টোনহোফার

@ ডেভিডটনহোফার আমি মনে করি আমাদের সর্বশেষ জেডিকে সঠিক বাগ-ফ্রি কোড থাকতে পারে, তবে যেহেতু জাভার মধ্যবর্তী .class ফাইলগুলি কোনও প্ল্যাটফর্মের সাথে কোনও সামঞ্জস্যপূর্ণ ভিএম দ্বারা ব্যাখ্যা করা যেতে পারে, আপনি নিশ্চিত হতে পারবেন না যে সেই ফিক্সগুলি সেই রানটাইমটিতে বিদ্যমান। অবশ্যই বেশিরভাগ সময় আপনি জানেন যে সার্ভারটি কোন সংস্করণটি চলছে, তবে প্রতিটি সংস্করণ পরীক্ষা করা বিরক্তিকর।
TWiStErRob

12

জাভাতে নিয়মিত প্রকাশের সাথে থ্রেড-সুরক্ষা

সারসংক্ষেপ:

জাভা নিয়মিত এক্সপ্রেশন এপিআই একক সংকলিত প্যাটার্নকে একাধিক ম্যাচের ক্রিয়াকলাপে ভাগ করার মঞ্জুরি দেওয়ার জন্য ডিজাইন করা হয়েছে।

আপনি বিভিন্ন থ্রেড থেকে একই প্যাটার্নে নিরাপদে প্যাটার্ন.ম্যাচার () কল করতে পারেন এবং একই সাথে ম্যাটারগুলি নিরাপদে ব্যবহার করতে পারেন। প্যাটার্ন.ম্যাচার () সিঙ্ক্রোনাইজেশন ছাড়াই ম্যাথারগুলি তৈরি করা নিরাপদ। যদিও পদ্ধতিটি সিঙ্ক্রোনাইজ করা হয়নি, প্যাটার্ন শ্রেণির অভ্যন্তরীণ, কম্পাইল নামে পরিচিত একটি উদ্বায়ী ভেরিয়েবল একটি প্যাটার্ন নির্মাণের পরে সর্বদা সেট করা হয় এবং কল টু ম্যাচারের শুরুতে পড়ে () read এটি প্যাটার্নটি উল্লেখ করে যে কোনও থ্রেডকে সেই বস্তুর বিষয়বস্তুগুলি সঠিকভাবে "দেখতে" বাধ্য করে।

অন্যদিকে, আপনার বিভিন্ন থ্রেডের মধ্যে ম্যাচার ভাগ করা উচিত নয়। বা কমপক্ষে, যদি আপনি কখনও করেন তবে আপনার সুস্পষ্ট সিঙ্ক্রোনাইজেশন ব্যবহার করা উচিত।


2
@akf, বিটিডাব্লু, আপনার অবশ্যই লক্ষ্য করা উচিত যে এটি একটি আলোচনার সাইট (অনেকটা এর মতো)। আপনি এখানে যে তথ্য পেয়েছেন তার চেয়ে ভাল বা খারাপ কোনটিই আমি বিবেচনা করব (যেমন এটি জেমস গোসলিংয়ের একমাত্র সত্য শব্দ নয়)।
বব ক্রস

3

আপনার মনে রাখতে হবে যে থ্রেড সুরক্ষাটিকে আশেপাশের কোডটিও ધ્યાનમાં নিতে হবে, আপনি ভাগ্যবান বলে মনে হয়। সত্য যে Matchers প্যাটার্ন এর ব্যবহার করে তৈরি করা হয় মিলকারীর কারখানা পদ্ধতি এবং পাবলিক কনস্ট্রাকটর অভাব একটি ইতিবাচক লক্ষণ। তেমনি, আপনি সংবেদী প্যাটার্ন তৈরি করতে সংকলন স্থিতি পদ্ধতিটি ব্যবহার করেন ।

সুতরাং, সংক্ষেপে আপনি যদি উদাহরণের মতো কিছু করেন:

Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();

আপনার বেশ ভাল করা উচিত।

স্পষ্টতার জন্য কোড উদাহরণটিতে ফলো-আপ করুন: নোট করুন যে এই উদাহরণটি দৃ strongly়ভাবে বোঝায় যে এইভাবে তৈরি ম্যাচার প্যাটার্ন এবং পরীক্ষার সাথে থ্রেড-স্থানীয়। অর্থাৎ, আপনাকে অন্য কোনও থ্রেডে এইভাবে তৈরি ম্যাচারটি প্রকাশ করা উচিত নয়।

সত্যই, এটি যে কোনও থ্রেড-সুরক্ষা প্রশ্নের ঝুঁকি। বাস্তবতা হ'ল আপনি যথেষ্ট চেষ্টা করলে যে কোনও কোড থ্রেড-অনিরাপদ তৈরি করা যায়। সৌভাগ্যক্রমে, এমন দুর্দান্ত বই রয়েছে যা আমাদের পুরো কোডকে আমাদের কোডটি নষ্ট করতে পারে teach যদি আমরা এই ভুলগুলি থেকে দূরে থাকি, আমরা থ্রেডিংয়ের সমস্যাগুলির নিজস্ব সম্ভাবনাটি ব্যাপকভাবে হ্রাস করি।


@ জেসন এস: থ্র্যান্ডের স্থানীয়তা থ্রেড সুরক্ষা অর্জনের এক সহজ সরল উপায় যদিও অভ্যন্তরীণ কোড থ্রেড নিরাপদ না থাকে। যদি কেবলমাত্র একবারে কোনও পদ্ধতি সম্ভবত কোনও নির্দিষ্ট পদ্ধতিতে অ্যাক্সেস করতে পারে তবে আপনি বাহ্যিকভাবে থ্রেড সুরক্ষা প্রয়োগ করেছেন।
বব ক্রস

1
ঠিক আছে, তাই আপনি কেবল বলছেন যে ব্যবহারের স্থানে স্ট্রিং থেকে একটি প্যাটার্নটি পুনরায় তৈরি করা, সার্থক সমস্যাগুলি মোকাবেলা করার ঝুঁকিতে দক্ষ হওয়ার জন্য এটি সংরক্ষণ করা ভাল? আমি আপনাকে এটি প্রদান করব। আমি কারখানার পদ্ধতি এবং পাবলিক কনস্ট্রাক্টর সম্পর্কে সেই বাক্যটি নিয়ে বিভ্রান্ত হয়ে পড়েছিলাম, এটি এই বিষয়টিকে একটি লাল রঙের হেরিংয়ের মতো বলে মনে হচ্ছে।
জেসন এস

@ জেসন এস, না, কারখানার পদ্ধতি এবং নির্মাতাদের অভাব এমন কয়েকটি উপায় যা আপনি অন্যান্য থ্রেডের সাথে মিলিত হওয়ার হুমকি হ্রাস করতে পারেন। আমার প্যাটার্নটির সাথে ম্যাচারটি পাওয়ার একমাত্র উপায় যদি পি.মাচার () এর মাধ্যমে হয় তবে অন্য কেউ আমার ম্যাচারকে পার্শ্ব-প্রতিক্রিয়া করতে পারে না। তবে, আমি এখনও আমার নিজের জন্য সমস্যা সৃষ্টি করতে পারি: যদি আমার কাছে এমন কোনও পাবলিক পদ্ধতি থাকে যা ম্যাচারকে ফিরিয়ে দেয় তবে অন্য থ্রেড এটি পেতে পারে এবং এটিকে পার্শ্ব-প্রতিক্রিয়াও করতে পারে। সংক্ষেপে, একমত হওয়া কঠিন (কোনও ভাষায়)।
বব ক্রস

2

কোডটির তাত্ক্ষণিক দৃষ্টিভঙ্গি Matcher.javaমেলানো হচ্ছে এমন পাঠ্য, গোষ্ঠীগুলির জন্য অ্যারে, অবস্থান বজায় রাখার জন্য কয়েকটি সূচী এবং booleanঅন্যান্য রাজ্যের জন্য কয়েকটি এস সহ কয়েকটি সদস্যের ভেরিয়েবলগুলি দেখায় । এটি সমস্ত এমন এক রাজ্যকে নির্দেশ করে Matcherযা একাধিক দ্বারা অ্যাক্সেস করা হলে ভাল আচরণ করবে না Threadsজাভাডোকটিও তাই করে :

এই শ্রেণীর উদাহরণ একাধিক সমবর্তী থ্রেড দ্বারা ব্যবহারের জন্য নিরাপদ নয়।

এটি কেবলমাত্র তখনই সমস্যা হয়, যখন @ Bob ক্রসটি নির্দেশ করে, আপনি Matcherআলাদাভাবে Threadএস ব্যবহার করার অনুমতি দেওয়ার জন্য আপনার পথ ছেড়ে চলে যান । আপনার যদি এটি করার দরকার হয় এবং আপনি মনে করেন যে সিঙ্ক্রোনাইজেশনটি আপনার কোডের জন্য একটি সমস্যা হয়ে দাঁড়াবে, আপনার কাছে একটি বিকল্প প্রতি কার্য থ্রেড ThreadLocalবজায় রাখার জন্য স্টোরেজ অবজেক্টটি ব্যবহার করা উচিত Matcher


1

সংক্ষেপে, আপনি সংকলিত প্যাটার্ন (গুলি) পুনরায় ব্যবহার করতে পারেন (স্ট্যাটিক ভেরিয়েবলগুলিতে রাখতে পারেন) এবং কিছু স্ট্রিংয়ের বিপরীতে re রেজেক্স প্যাটেনগুলি যাচাই করার প্রয়োজন হলে আপনাকে নতুন ম্যাচারার দেওয়ার জন্য তাদের বলতে পারেন

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Validation helpers
 */
public final class Validators {

private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";

private static Pattern email_pattern;

  static {
    email_pattern = Pattern.compile(EMAIL_PATTERN);
  }

  /**
   * Check if e-mail is valid
   */
  public static boolean isValidEmail(String email) { 
    Matcher matcher = email_pattern.matcher(email);
    return matcher.matches();
  }

}

দেখতে http://zoomicon.wordpress.com/2012/06/01/validating-e-mails-using-regular-expressions-in-java/ (শেষ নিকটে) ই-মেইল যাচাই করার জন্য উপরে ব্যবহৃত Regex প্যাটার্ন সংক্রান্ত ( যদি এটি ইমেল বৈধতার জন্য এটি পোস্ট করা হয় তবে এটির প্রয়োজনের সাথে এটি মাপসই না হয়)


3
আপনার উত্তর পোস্ট করার জন্য ধন্যবাদ! দয়া করে স্ব-প্রচারের এফএকিউ অবশ্যই মনোযোগ সহকারে পড়তে ভুলবেন না । কেউ এই উত্তরটি এবং লিঙ্ক -যুক্ত ব্লগ পোস্ট দেখতে পাবে এবং মনে করে আপনি ব্লগ পোস্টটি কেবল পোস্ট করেছেন যাতে আপনি এখান থেকে লিঙ্ক করতে পারেন।
অ্যান্ড্রু বারবার

2
কেন বিরক্ত করবেন static {}? আপনি সেই পরিবর্তনশীল সূচনাটি ইনলাইন করতে এবং Pattern finalপাশাপাশি তৈরি করতে পারেন ।
TWiStErRob

1
আমি TWiStErRob এর উপপত্তি দ্বিতীয়: private static final Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);এটি আরও ভাল।
ক্রিস্টোফ রাউসি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.