markdown Java MultiThreading第四部分

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Java MultiThreading第四部分相关的知识,希望对你有一定的参考价值。

#Java MultiThreading Part IV

##Lesson 12 : Callable & Future

How to use *`Callable`* and *`Future`* in Java to get results from your **threads** and to allow your threads to throw exceptions. 
Plus, *`Future`* allows you to control your threads, checking to see if they're running or not, waiting for results and even interrupting them or descheduling them. 

###1. Simple Way 

**App.java**
```java
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
 * Callable & Future
 */
public class App {

	public static void main(String[] args) {
		ExecutorService executor = Executors.newCachedThreadPool();
		
		executor.submit(new Runnable(){

			@Override
			public void run() {
				Random random = new Random();
				int duration = random.nextInt(4000);
				
				System.out.println("Starting....");
				try {
					Thread.sleep(duration);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				System.out.println("Finish....");
			}
			
		});
		
		executor.shutdown();
	}//ENDof Main()
}

```

**OUTPUT**
```
Starting....
Finish....
```

###2. Use Callable & Future 

```java
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/*
 * Callable & Future
 */
public class App {

	public static void main(String[] args) {
		ExecutorService executor = Executors.newCachedThreadPool();
		
		//Callable & Future
		Future<Integer> future = executor.submit(new Callable<Integer>() {

			@Override
			public Integer call() throws Exception {
				Random random = new Random();
				int duration = random.nextInt(4000);
				
				System.out.println("Starting....");
				try {
					Thread.sleep(duration);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				System.out.println("Finish....");
				
				return duration;
			}
			
		});
		
		executor.shutdown();
		try {
			System.out.println("Result: " + future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}//ENDof Main()
}

```

**OUTPUT**
```
Starting....
Finish....
Result: 3672

```

###3. Throw Exception for Callable
```java
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/*
 * Callable & Future
 */
public class App {

	public static void main(String[] args) {
		ExecutorService executor = Executors.newCachedThreadPool();
		
		//Callable & Future
		Future<Integer> future = executor.submit(new Callable<Integer>() {

			@Override
			public Integer call() throws Exception {
				Random random = new Random();
				int duration = random.nextInt(4000);
				
				if (duration > 2000){
					throw new IOException("Sleeping for too long");
				}
				System.out.println("Starting....");
				try {
					Thread.sleep(duration);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				System.out.println("Finish....");
				
				return duration;
			}
			
		});
		
		executor.shutdown();
		try {
			//Future.get()
			//Throws CancellationException
			//Throws InterruptedException 
			//Throws ExecutionException 
			System.out.println("Result: " + future.get()); 
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			//IOException ex = (IOException) e.getCause();
			//System.out.println(ex.getMessage());   // "Sleeping for too long"
			System.out.println(e.getMessage());;
		}
	}//ENDof Main()
}

```

**OUTPUT**
```
java.io.IOException: Sleeping for too long
```


##Lesson 13 : Interrupting Threads (InterruptedExceptions)

```java
import java.util.Random;

/*
 * Interrupting Threads
 */
public class App {

	public static void main(String[] args) throws InterruptedException {
		System.out.println("Starting...");
		
		Thread t1 = new Thread(new Runnable() {

			@Override
			public void run() {
				Random random = new Random();
				
				// 1E10 => 1 x (10 ^ 6)
				for(int i = 0; i < 1E8; i++){
					
					//Check if is being interrupted
					if ( Thread.currentThread().isInterrupted() ){
						System.out.println("Interrupted!!!");
						break;
					}
					
					/*try{
						Thread.sleep(1);
					}catch(InterruptedException e){
						System.out.println("Interrupted!!!");
						break;
					}*/
					Math.sin(random.nextDouble());
				}
			}
			
		});
		
		t1.start();
		
		Thread.sleep(500);
		//Set Flag tells that it is being interrupted
		//Does not terminate 
		t1.interrupt(); 
		
		t1.join();
		
		System.out.println("Finished...");
	}//ENDof Main()

}

```

**OUTPUT**
```
Starting...
Interrupted!!!
Finished...

```

##Lesson 14 : MultiThreading in Swing with (SwingWorker)

**App.java**
```java
import javax.swing.SwingUtilities;


public class App {

    /**
     * @param args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            
            @Override
            public void run() {
                new MainFrame("SwingWorker Demo");
            }
        });
    }

}

```

**MainFrame.java**

```java
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingWorker;

public class MainFrame extends JFrame {

    private JLabel countLabel1 = new JLabel("0");
    private JLabel statusLabel = new JLabel("Task not completed.");
    private JButton startButton = new JButton("Start");

    public MainFrame(String title) {
        super(title);

        setLayout(new GridBagLayout());

        GridBagConstraints gc = new GridBagConstraints();

        gc.fill = GridBagConstraints.NONE;

        gc.gridx = 0;
        gc.gridy = 0;
        gc.weightx = 1;
        gc.weighty = 1;
        add(countLabel1, gc);

        gc.gridx = 0;
        gc.gridy = 1;
        gc.weightx = 1;
        gc.weighty = 1;
        add(statusLabel, gc);

        gc.gridx = 0;
        gc.gridy = 2;
        gc.weightx = 1;
        gc.weighty = 1;
        add(startButton, gc);

        startButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                start();
            }
        });

        setSize(200, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private void start() {
        
        // Use SwingWorker<Void, Void> and return null from doInBackground if
        // you don't want any final result and you don't want to update the GUI
        // as the thread goes along.
        // First argument is the thread result, returned when processing finished.
        // Second argument is the value to update the GUI with via publish() and process()
        SwingWorker<Boolean, Integer> worker = new SwingWorker<Boolean, Integer>() {

            @Override
            /*
             * Note: do not update the GUI from within doInBackground.
             */
            protected Boolean doInBackground() throws Exception {
                
                // Simulate useful work
                for(int i=0; i<30; i++) {
                    Thread.sleep(100);
                    System.out.println("Hello: " + i);
                    
                    // optional: use publish to send values to process(), which
                    // you can then use to update the GUI.
                    publish(i);
                }
                
                return false;
            }

            @Override
            // This will be called if you call publish() from doInBackground()
            // Can safely update the GUI here.
            protected void process(List<Integer> chunks) {
                Integer value = chunks.get(chunks.size() - 1);
                
                countLabel1.setText("Current value: " + value);
            }

            @Override
            // This is called when the thread finishes.
            // Can safely update GUI here.
            protected void done() {
                
                try {
                    Boolean status = get();
                    statusLabel.setText("Completed with status: " + status);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
            }
            
        };
        
        worker.execute();
    }
}
 
```

##Resources
1. [Back to JAVA MultiThreading Part III](https://gist.github.com/yclim95/e86db3971f844080db1cb70697477ec9)
2. [Main Contents](https://gist.github.com/yclim95/821d7059767dfc098eaa6698490bb1a0)

以上是关于markdown Java MultiThreading第四部分的主要内容,如果未能解决你的问题,请参考以下文章

python multithread task_done

MultiThread(VS2013 MFC多线程-含源码-含个人逐步实现文档)

多线程--MultiThread

Multithread 什么时候处理多线程,有几种方式,优缺点?

MultiThread SkinnedMeshRenderer原理及实现

MultiThread SkinnedMeshRenderer原理及实现