আপনি java.lang.Thread
জাভাতে কীভাবে মারবেন ?
ExecutorStatus
: এই প্রশ্নে stackoverflow.com/questions/2275443/how-to-timeout-a-thread
আপনি java.lang.Thread
জাভাতে কীভাবে মারবেন ?
ExecutorStatus
: এই প্রশ্নে stackoverflow.com/questions/2275443/how-to-timeout-a-thread
উত্তর:
কেন তারা হতাশ হয়েছে সে সম্পর্কে সূরারThread.stop()
এই থ্রেডটি দেখুন । এটি কেন একটি খারাপ পদ্ধতি ছিল এবং সাধারণভাবে থ্রেডগুলি নিরাপদে থামাতে কী করা উচিত সে সম্পর্কে বিশদে এটি যায়।
তারা যেভাবে প্রস্তাব দেয় তা হ'ল একটি ভাগ হিসাবে একটি ভাগ করা পরিবর্তনশীল যা পটভূমি থ্রেডটি থামতে বলে। এই ভেরিয়েবলটি থ্রেড সমাপ্তির অনুরোধ করে কোনও আলাদা অবজেক্ট দ্বারা সেট করা যেতে পারে।
getConnection()
থেকে পদ্ধতি ব্যবহার java.sql.DriverManager
। যদি সংযোগের প্রত্যয়টি বেশি সময় নেয় আমি সংশ্লিষ্ট থ্রেডটিকে কল করে হত্যা করার চেষ্টা করি Thread.interrupt()
তবে এটি থ্রেডকে মোটেই প্রভাবিত করে না। Thread.stop()
তবে কাজ করে, যদিও ওরাকল যদি এটা কাজ করা উচিত নয় বলে interrupt()
না। আমি ভাবছি কীভাবে এটি কার্যকর হয় এবং অবচয় পদ্ধতি ব্যবহার করা এড়ানো যায়।
সাধারণত আপনি না ..
আপনি এটি থ্রেড.ইনটার্নপ্রেট (জাভাদোক লিঙ্ক) ব্যবহার করে যা কিছু করছে তা বিঘ্নিত করতে বলুন
কেন জাভাডোকে রয়েছে তার একটি ভাল ব্যাখ্যা (জাভা টেকনোট লিঙ্ক)
interrupt()
পদ্ধতিটি বলা হয় তখন থ্রেড প্রসঙ্গে কী হবে ? মূল প্রশ্ন প্রতিটি নতুন থ্রেডের জন্য লগ উত্পাদন সম্পর্কিত ।
জাভা থ্রেডগুলি হত্যা করা হয় না, তবে থ্রেড থামানো একটি সমবায় উপায়ে করা হয় । থ্রেডটি সমাপ্ত করতে বলা হয় এবং থ্রেডটি তখন নিখুঁতভাবে বন্ধ করতে পারে।
প্রায়শই এমন volatile boolean
ক্ষেত্র ব্যবহার করা হয় যা সংশ্লিষ্ট মানটিতে সেট করা হলে থ্রেড পর্যায়ক্রমে পরীক্ষা করে শেষ করে।
থ্রেডটি শেষ হওয়া উচিত কিনা তা পরীক্ষা করার জন্য আমি একটি ব্যবহার করব না । আপনি ব্যবহার করেন তাহলে একটি ক্ষেত্র পরিবর্তক হিসাবে, এই নির্ভরযোগ্য কাজ করবে, কিন্তু আপনার কোড আরো জটিল, পরিবর্তে ভিতরে অন্যান্য ব্লক পদ্ধতি ব্যবহার জন্য হয় তাহলে লুপ, এটা ঘটতে পারে, যে আপনার কোড হবে বিনষ্ট না এ সব অথবা অন্তত বেশী সময় লাগে আপনি চাইবে।boolean
volatile
while
কিছু ব্লক করা গ্রন্থাগার পদ্ধতি বাধা সমর্থন করে।
প্রতিটি থ্রেডের ইতিমধ্যে একটি বুলিয়ান পতাকা বাধার স্থিতি রয়েছে এবং আপনার এটি ব্যবহার করা উচিত। এটি এভাবে প্রয়োগ করা যেতে পারে:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
অনুশীলনে জাভা কনকুরঞ্জি থেকে উত্সযুক্ত কোড উত্স । যেহেতু cancel()
পদ্ধতিটি সর্বজনীন, আপনি যেমন চান তেমন অন্য থ্রেডকে এই পদ্ধতিতে ডাকতে দিতে পারেন।
একটি উপায় হ'ল একটি ক্লাস ভেরিয়েবল সেট করা এবং এটিকে সেন্ডিনেল হিসাবে ব্যবহার করা।
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
উপরের উদাহরণে একটি বাহ্যিক শ্রেণীর পরিবর্তনশীল, যেমন পতাকা = সত্য সেট করুন। থ্রেডটিকে 'হত্যা' করতে এটি মিথ্যাতে সেট করুন।
volatile
এটি যে কোনও জায়গায় সঠিকভাবে কাজ করে তা নিশ্চিত করতে "পতাকা" তৈরি করুন । অভ্যন্তর শ্রেণি স্থির নয়, তাই পতাকাটি একটি উদাহরণ পরিবর্তনশীল হওয়া উচিত। পতাকাটি একটি অ্যাক্সেসর পদ্ধতিতে সাফ করা উচিত যাতে অন্যান্য ক্রিয়াকলাপ (যেমন বিঘ্নিত) সম্পাদন করা যায়। "পতাকা" নামটি বর্ণনামূলক নয়।
আপনি এটি করতে পারেন এমন একটি উপায় রয়েছে is তবে যদি এটি ব্যবহার করতে হয় তবে হয় আপনি খারাপ প্রোগ্রামার বা আপনি খারাপ প্রোগ্রামারদের দ্বারা লিখিত কোড ব্যবহার করছেন। সুতরাং, আপনার খারাপ প্রোগ্রামার হওয়া বা এই খারাপ কোডটি ব্যবহার বন্ধ করা সম্পর্কে ভাবা উচিত। এই সমাধানটি কেবল তখনই পরিস্থিতিগুলির জন্য যখন অন্য কোনও উপায় নেই।
Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
Thread.stop
অবহেলা করা সত্ত্বেও এটি কল করা সম্ভব ।
Thread.stop
একই কাজ করে তবে অ্যাক্সেস এবং অনুমতিও পরীক্ষা করে। ব্যবহার Thread.stop
করা বরং সুস্পষ্ট এবং আমি কেন এটির Thread.stop0
পরিবর্তে কেন ব্যবহার করেছি তা মনে নেই । সম্ভবত Thread.stop
আমার বিশেষ ক্ষেত্রে (জাভা 6 তে ওয়েবলোগিক) কাজ করে না। বা হতে পারে কারণ Thread.stop
হ্রাস করা হয়েছে এবং সতর্কতার কারণ ঘটেছে।
জমা হওয়া মন্তব্যের ভিত্তিতে আমি কয়েকটি পর্যবেক্ষণ যুক্ত করতে চাই।
Thread.stop()
সুরক্ষা পরিচালক যদি এটি অনুমতি দেয় তবে একটি থ্রেড বন্ধ করবে।Thread.stop()
বিপদজনক. এই বলে যে, আপনি যদি কোন জেইই পরিবেশে কাজ করছেন এবং কোডটি কল করার বিষয়ে আপনার কোনও নিয়ন্ত্রণ নেই, এটি প্রয়োজনীয় হতে পারে; দেখতে কেন Thread.stop অবচিত?stop()
কলিং থ্রেডে একটি নতুন ThreadDeathError
ত্রুটি তৈরি করে এবং তারপরে সেই ত্রুটিটিকে লক্ষ্য থ্রেডে ফেলে দেয় । অতএব, স্ট্যাক ট্রেস সাধারণত মূল্যহীন।stop()
নিরাপত্তা ম্যানেজার দিয়ে চেক এবং তারপর কল stop1()
যে কল stop0()
। stop0()
নেটিভ কোড।Thread.stop()
তে সরানো হয়নি (এখনও), তবে Thread.stop(Throwable)
জাভা ১১-এ সরানো হয়েছে ( মেলিং তালিকা , জেডিকে -8204243 )আমি ভোট চাই Thread.stop()
।
উদাহরণস্বরূপ আপনার দীর্ঘস্থায়ী ক্রিয়াকলাপ রয়েছে (যেমন নেটওয়ার্ক অনুরোধ)। সম্ভবত আপনি কোনও প্রতিক্রিয়ার জন্য অপেক্ষা করছেন তবে এটি সময় নিতে পারে এবং ব্যবহারকারীটি অন্য ইউআইতে নেভিগেট করে। এই অপেক্ষার থ্রেডটি এখন ক) অকেজো খ) সম্ভাব্য সমস্যা কারণ যখন সে ফলাফল পাবে, এটি সম্পূর্ণ অকেজো এবং তিনি কলব্যাকগুলি ট্রিগার করবেন যা ত্রুটি সংখ্যার দিকে পরিচালিত করতে পারে।
এই সমস্ত এবং তিনি সিপিইউ তীব্র হতে পারে এমন প্রতিক্রিয়া প্রক্রিয়াকরণ করতে পারেন। এবং আপনি, একজন বিকাশকারী হিসাবে এটিকে থামাতেও পারবেন না, কারণ আপনি if (Thread.currentThread().isInterrupted())
সমস্ত কোডে লাইন ফেলে দিতে পারবেন না ।
সুতরাং কোনও থ্রেডকে জোর করে আটকাতে না পারা অক্ষম।
Thread.stop()
নিরাপদে কল করতে পারবেন না । আপনি ভোট দিচ্ছেন না Thread.stop()
, আপনি প্রতিটি ব্যক্তিকে জিজ্ঞাসা করছেন যিনি প্রতিটি ক্রিয়াকলাপ কার্যকর করেন যা এটি নিরাপদভাবে অ্যাওরটেবল করতে দীর্ঘ সময় নিতে পারে। এবং এটি ভাল ধারণা হতে পারে Thread.stop()
তবে নিরাপদ গর্ভপাতের অনুরোধ করার উপায় হিসাবে এটি প্রয়োগের সাথে কিছুই করার নেই । আমরা ইতিমধ্যে তার interrupt
জন্য আছে ।
stop
।
প্রশ্নটি বরং অস্পষ্ট। যদি আপনি বোঝাতে চেয়েছিলেন যে "আমি কীভাবে কোনও প্রোগ্রাম লিখি যাতে থ্রেডটি যখন চাইলে থেমে থেমে যায়", তবে অন্যান্য বিভিন্ন প্রতিক্রিয়া সহায়ক হবে। তবে যদি আপনি বোঝাতে চেয়েছিলেন যে "আমার একটি সার্ভারের সাথে জরুরী অবস্থা আছে আমি এখনই পুনরায় আরম্ভ করতে পারছি না এবং মরার জন্য আমার কেবল একটি নির্দিষ্ট থ্রেড দরকার, যা ঘটতে পারে আসুন", তারপরে আপনার যেমন পর্যবেক্ষণের সরঞ্জামগুলি মেলাতে হস্তক্ষেপের সরঞ্জাম প্রয়োজন jstack
।
এই উদ্দেশ্যে আমি জিলিথ্রেড তৈরি করেছি । ব্যবহারের জন্য এর নির্দেশাবলী দেখুন।
অবশ্যই এমন কোনও ক্ষেত্রে রয়েছে যেখানে আপনি কোনও ধরণের সম্পূর্ণরূপে-নির্ভরযোগ্য কোডটি চালাচ্ছেন। (আমার ব্যক্তিগতভাবে আমার জাভা পরিবেশে আপলোড করা স্ক্রিপ্টগুলি কার্যকর করার অনুমতি দিয়ে আমি এটি পেয়েছি Yes হ্যাঁ, সর্বত্র সুরক্ষা অ্যালার্ম বেল বাজছে তবে এটি প্রয়োগের অংশ)) এই দুর্ভাগ্যক্রমে আপনি প্রথমে স্ক্রিপ্ট লেখকদের জিজ্ঞাসা করে কেবল আশাবাদী হচ্ছেন কিছু ধরণের বুলিয়ান রান / চালান না সংকেতকে সম্মান জানাতে। আপনার একমাত্র শালীন ব্যর্থ নিরাপদ হ'ল থ্রেডে স্টপ পদ্ধতিটি কল করা যদি বলা হয়, এটি কিছু সময়সীমার চেয়ে দীর্ঘ চলে।
তবে এটি কেবল "শালীন", এবং নিখুঁত নয়, কারণ কোডটি থ্রেডডিথ ত্রুটিটি (বা আপনি যে কোনও ব্যতিক্রম স্পষ্টভাবে নিক্ষেপ করতে পারেন) ধরতে পারে এবং ভদ্রলোকের থ্রেডের মতো এটি পুনর্বার নয়। সুতরাং, নীচের লাইনটি এএফএআইএ কোনও নিরাপদ ব্যর্থ নেই fail
দয়া করে কোনও থ্রেড মেরে ফেলার কোনও উপায় নেই।
আপনি থ্রেডকে বাধা দেওয়ার চেষ্টা করতে পারেন, একটি কমন্স কৌশল হ'ল থ্রেডটি নিজেকে থামানোর জন্য বার্তা দেওয়ার জন্য একটি বিষের বড়ি ব্যবহার করা
public class CancelSupport {
public static class CommandExecutor implements Runnable {
private BlockingQueue<String> queue;
public static final String POISON_PILL = “stopnow”;
public CommandExecutor(BlockingQueue<String> queue) {
this.queue=queue;
}
@Override
public void run() {
boolean stop=false;
while(!stop) {
try {
String command=queue.take();
if(POISON_PILL.equals(command)) {
stop=true;
} else {
// do command
System.out.println(command);
}
} catch (InterruptedException e) {
stop=true;
}
}
System.out.println(“Stopping execution”);
}
}
}
BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);
সাধারণত আপনি কোনও থ্রেড মেরে, থামেন না বা বাধেন না (বা এটি পরীক্ষা করুন) এটি স্বাভাবিকভাবেই শেষ করতে দিন।
এটা সহজ. থ্রেডের ক্রিয়াকলাপ নিয়ন্ত্রণ করতে আপনি কোনও কোনও লুপ (অস্থির) বুলিয়ান ভেরিয়েবলের ভিতরে রান () পদ্ধতির সাথে একসাথে ব্যবহার করতে পারেন। এটি বন্ধ করতে আপনি সক্রিয় থ্রেড থেকে মূল থ্রেডে ফিরে আসতে পারেন।
আপনি নিখুঁতভাবে একটি থ্রেড হত্যা :)।
আকস্মিক থ্রেড সমাপ্তির চেষ্টাগুলি সুপরিচিত খারাপ প্রোগ্রামিং অনুশীলন এবং দুর্বল অ্যাপ্লিকেশন ডিজাইনের প্রমাণ। মাল্টিথ্রেডেড অ্যাপ্লিকেশনটির সমস্ত থ্রেড সুস্পষ্টভাবে এবং স্পষ্টভাবে একই প্রক্রিয়া স্থিতি ভাগ করে এবং একে ধারাবাহিক রাখতে একে অপরের সাথে সহযোগিতা করতে বাধ্য হয়, অন্যথায় আপনার অ্যাপ্লিকেশনটি বাগগুলি প্রবণ হবে যা নির্ণয় করা সত্যই কঠিন। সুতরাং, যত্নবান এবং পরিষ্কার অ্যাপ্লিকেশন ডিজাইনের মাধ্যমে এ জাতীয় ধারাবাহিকতার একটি নিশ্চয়তা প্রদান করা বিকাশকারীর একটি দায়িত্ব।
নিয়ন্ত্রিত থ্রেড সমাপ্তির জন্য প্রধান দুটি সঠিক সমাধান রয়েছে:
আকস্মিক থ্রেড সমাপ্তি সম্পর্কিত সমস্যাগুলির ভাল এবং বিস্তারিত ব্যাখ্যা পাশাপাশি নিয়ন্ত্রিত থ্রেড সমাপ্তির জন্য ভুল এবং সঠিক সমাধানের উদাহরণগুলি এখানে পাওয়া যাবে:
বিষয়টিতে বেশ কয়েকটি ভাল পড়া এখানে দেওয়া হয়েছে:
অ্যান্ড্রয়েডে কাজ করতে আমি বাধা পাইনি, তাই আমি এই পদ্ধতিটি ব্যবহার করেছি, পুরোপুরি কাজ করে:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
'একটি থ্রেড হত্যা' ব্যবহার করার সঠিক বাক্য নয়। এখানে আমরা ইচ্ছামতো সুদৃ completion়ভাবে সমাপ্তি / থ্রেডের প্রস্থানটি কার্যকর করতে পারি তার একটি উপায় এখানে:
চলমান যা আমি ব্যবহার করেছি:
class TaskThread implements Runnable {
boolean shouldStop;
public TaskThread(boolean shouldStop) {
this.shouldStop = shouldStop;
}
@Override
public void run() {
System.out.println("Thread has started");
while (!shouldStop) {
// do something
}
System.out.println("Thread has ended");
}
public void stop() {
shouldStop = true;
}
}
ট্রিগার ক্লাস:
public class ThreadStop {
public static void main(String[] args) {
System.out.println("Start");
// Start the thread
TaskThread task = new TaskThread(false);
Thread t = new Thread(task);
t.start();
// Stop the thread
task.stop();
System.out.println("End");
}
}
থ্রেড.স্টপকে অবমূল্যায়ন করা হয়েছে তাই আমরা কীভাবে জাভাতে কোনও থ্রেড থামাব?
বাতিল করার অনুরোধ করতে সর্বদা বিঘ্নিত পদ্ধতি এবং ভবিষ্যত ব্যবহার করুন
Callable < String > callable = new Callable < String > () {
@Override
public String call() throws Exception {
String result = "";
try {
//assume below take method is blocked as no work is produced.
result = queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return result;
}
};
Future future = executor.submit(callable);
try {
String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Thread timedout!");
return "";
} finally {
//this will call interrupt on queue which will abort the operation.
//if it completes before time out, it has no side effects
future.cancel(true);
}
public interface CustomCallable < T > extends Callable < T > {
void cancel();
RunnableFuture < T > newTask();
}
public class CustomExecutorPool extends ThreadPoolExecutor {
protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
if (callable instanceof CancellableTask)
return ((CancellableTask < T > ) callable).newTask();
else
return super.newTaskFor(callable);
}
}
public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
public synchronized void cancel() {
try {
obj.close();
} catch (IOException e) {
logger.error("io exception", e);
}
}
public RunnableFuture < T > newTask() {
return new FutureTask < T > (this) {
public boolean cancel(boolean mayInterruptIfRunning) {
try {
this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}