├── .gitignore ├── README.md ├── Thread1 ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs └── src │ ├── demo1 │ └── Application.java │ ├── demo2 │ └── Application.java │ └── demo3 │ └── Application.java ├── Thread10 ├── .classpath ├── .project └── src │ └── demo1 │ ├── App.java │ └── Runner.java ├── Thread11 ├── .classpath ├── .project └── src │ └── demo1 │ ├── Account.java │ ├── App.java │ └── Runner.java ├── Thread12 ├── .classpath ├── .project └── src │ └── demo1 │ ├── App.java │ └── Connection.java ├── Thread13 ├── .classpath ├── .project └── src │ └── demo1 │ └── App.java ├── Thread14 ├── .classpath ├── .project └── src │ └── demo1 │ └── App.java ├── Thread15 ├── .classpath ├── .project └── src │ └── demo1 │ ├── App.java │ └── MainFrame.java ├── Thread2 ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs └── src │ └── demo1 │ └── App.java ├── Thread3 ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs └── src │ └── demo1 │ └── Worker.java ├── Thread4 ├── .classpath ├── .project └── src │ └── demo1 │ ├── App.java │ └── Worker.java ├── Thread5 ├── .classpath ├── .project └── src │ └── demo1 │ └── App.java ├── Thread6 ├── .classpath ├── .project └── src │ └── demo1 │ └── App.java ├── Thread7 ├── .classpath ├── .project └── src │ └── demo1 │ └── App.java ├── Thread8 ├── .classpath ├── .project └── src │ └── demo1 │ ├── App.java │ └── Processor.java └── Thread9 ├── .classpath ├── .project └── src └── demo1 ├── App.java └── Processor.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | udemy-java_multithreading 2 | ========================= 3 | 4 | Java multithreading course at Udemy 5 | 6 | 7 | Course Syllabus: 8 | --------------- 9 | 1. Starting Threads 10 | 2. Basic Thread Synchronization 11 | 3. The Synchronized Keyword 12 | 4. Multiple Locks; Using Synchronized Code Blocks 13 | 5. Thread Pools 14 | 6. Countdown Latches 15 | 7. Producer-Consumer 16 | 8. Wait and Notify 17 | 9. A Worked Example Using Low-Level Synchronization 18 | 10. Re-entrant Locks 19 | 11. Deadlock 20 | 12. Semaphores 21 | 13. Callable and Future 22 | 14. Interrupting Threads 23 | 15. Multithreading in Swing with SwingWorker 24 | 25 | 26 | More info: https://www.udemy.com/java-multithreading 27 | -------------------------------------------------------------------------------- /Thread1/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread1/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread1 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread1/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.6 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.6 12 | -------------------------------------------------------------------------------- /Thread1/src/demo1/Application.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | class Runner extends Thread { 4 | 5 | @Override 6 | public void run() { 7 | for (int i = 0; i < 5; i++) { 8 | System.out.println("Hello: " + i); 9 | 10 | try { 11 | Thread.sleep(100); 12 | } catch (InterruptedException e) { 13 | e.printStackTrace(); 14 | } 15 | } 16 | } 17 | 18 | } 19 | 20 | public class Application { 21 | 22 | public static void main(String[] args) { 23 | Runner runner1 = new Runner(); 24 | runner1.start(); 25 | 26 | Runner runner2 = new Runner(); 27 | runner2.start(); 28 | 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /Thread1/src/demo2/Application.java: -------------------------------------------------------------------------------- 1 | package demo2; 2 | 3 | class Runner implements Runnable { 4 | 5 | @Override 6 | public void run() { 7 | for (int i = 0; i < 5; i++) { 8 | System.out.println("Hello: " + i); 9 | 10 | try { 11 | Thread.sleep(100); 12 | } catch (InterruptedException e) { 13 | e.printStackTrace(); 14 | } 15 | } 16 | 17 | } 18 | 19 | } 20 | 21 | public class Application { 22 | 23 | public static void main(String[] args) { 24 | Thread thread1 = new Thread(new Runner()); 25 | thread1.start(); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /Thread1/src/demo3/Application.java: -------------------------------------------------------------------------------- 1 | package demo3; 2 | 3 | public class Application { 4 | 5 | public static void main(String[] args) { 6 | Thread thread1 = new Thread(new Runnable() { 7 | 8 | @Override 9 | public void run() { 10 | for (int i = 0; i < 5; i++) { 11 | System.out.println("Hello: " + i); 12 | 13 | try { 14 | Thread.sleep(100); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | } 19 | 20 | } 21 | 22 | }); 23 | 24 | thread1.start(); 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /Thread10/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread10/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread10 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread10/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | public class App { 4 | 5 | public static void main(String[] args) throws Exception { 6 | 7 | final Runner runner = new Runner(); 8 | 9 | Thread t1 = new Thread(new Runnable() { 10 | public void run() { 11 | try { 12 | runner.firstThread(); 13 | } catch (InterruptedException e) { 14 | e.printStackTrace(); 15 | } 16 | } 17 | }); 18 | 19 | Thread t2 = new Thread(new Runnable() { 20 | public void run() { 21 | try { 22 | runner.secondThread(); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | }); 28 | 29 | t1.start(); 30 | t2.start(); 31 | 32 | t1.join(); 33 | t2.join(); 34 | 35 | runner.finished(); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /Thread10/src/demo1/Runner.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.Scanner; 4 | import java.util.concurrent.locks.Condition; 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | public class Runner { 9 | 10 | private int count = 0; 11 | private Lock lock = new ReentrantLock(); 12 | private Condition cond = lock.newCondition(); 13 | 14 | private void increment() { 15 | for (int i = 0; i < 10000; i++) { 16 | count++; 17 | } 18 | } 19 | 20 | public void firstThread() throws InterruptedException { 21 | lock.lock(); 22 | 23 | System.out.println("Waiting ...."); 24 | cond.await(); 25 | 26 | System.out.println("Woken up!"); 27 | 28 | try { 29 | increment(); 30 | } finally { 31 | lock.unlock(); 32 | } 33 | } 34 | 35 | public void secondThread() throws InterruptedException { 36 | 37 | Thread.sleep(1000); 38 | lock.lock(); 39 | 40 | System.out.println("Press the return key!"); 41 | new Scanner(System.in).nextLine(); 42 | System.out.println("Got return key!"); 43 | 44 | cond.signal(); 45 | 46 | try { 47 | increment(); 48 | } finally { 49 | lock.unlock(); 50 | } 51 | } 52 | 53 | public void finished() { 54 | System.out.println("Count is: " + count); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Thread11/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread11/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread11 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread11/src/demo1/Account.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | public class Account { 4 | private int balance = 10000; 5 | 6 | public void deposit(int amount) { 7 | balance += amount; 8 | } 9 | 10 | public void withdraw(int amount) { 11 | balance -= amount; 12 | } 13 | 14 | public int getBalance() { 15 | return balance; 16 | } 17 | 18 | public static void transfer(Account acc1, Account acc2, int amount) { 19 | acc1.withdraw(amount); 20 | acc2.deposit(amount); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Thread11/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | public class App { 4 | 5 | public static void main(String[] args) throws Exception { 6 | 7 | final Runner runner = new Runner(); 8 | 9 | Thread t1 = new Thread(new Runnable() { 10 | public void run() { 11 | try { 12 | runner.firstThread(); 13 | } catch (InterruptedException e) { 14 | e.printStackTrace(); 15 | } 16 | } 17 | }); 18 | 19 | Thread t2 = new Thread(new Runnable() { 20 | public void run() { 21 | try { 22 | runner.secondThread(); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | }); 28 | 29 | t1.start(); 30 | t2.start(); 31 | 32 | t1.join(); 33 | t2.join(); 34 | 35 | runner.finished(); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /Thread11/src/demo1/Runner.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.locks.Lock; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | public class Runner { 8 | private Account acc1 = new Account(); 9 | private Account acc2 = new Account(); 10 | 11 | private Lock lock1 = new ReentrantLock(); 12 | private Lock lock2 = new ReentrantLock(); 13 | 14 | private void acquireLocks(Lock firstLock, Lock secondLock) 15 | throws InterruptedException { 16 | while (true) { 17 | // Acquire locks 18 | 19 | boolean gotFirstLock = false; 20 | boolean gotSecondLock = false; 21 | 22 | try { 23 | gotFirstLock = firstLock.tryLock(); 24 | gotSecondLock = secondLock.tryLock(); 25 | } finally { 26 | if (gotFirstLock && gotSecondLock) { 27 | return; 28 | } 29 | 30 | if (gotFirstLock) { 31 | firstLock.unlock(); 32 | } 33 | 34 | if (gotSecondLock) { 35 | secondLock.unlock(); 36 | } 37 | } 38 | 39 | // Locks not acquired 40 | Thread.sleep(1); 41 | } 42 | } 43 | 44 | public void firstThread() throws InterruptedException { 45 | 46 | Random random = new Random(); 47 | 48 | for (int i = 0; i < 10000; i++) { 49 | 50 | acquireLocks(lock1, lock2); 51 | 52 | try { 53 | Account.transfer(acc1, acc2, random.nextInt(100)); 54 | } finally { 55 | lock1.unlock(); 56 | lock2.unlock(); 57 | } 58 | } 59 | } 60 | 61 | public void secondThread() throws InterruptedException { 62 | Random random = new Random(); 63 | 64 | for (int i = 0; i < 10000; i++) { 65 | 66 | acquireLocks(lock2, lock1); 67 | 68 | try { 69 | Account.transfer(acc2, acc1, random.nextInt(100)); 70 | } finally { 71 | lock1.unlock(); 72 | lock2.unlock(); 73 | } 74 | } 75 | } 76 | 77 | public void finished() { 78 | System.out.println("Account 1 balance: " + acc1.getBalance()); 79 | System.out.println("Account 2 balance: " + acc2.getBalance()); 80 | System.out.println("Total balance: " 81 | + (acc1.getBalance() + acc2.getBalance())); 82 | } 83 | } -------------------------------------------------------------------------------- /Thread12/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread12/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread12 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread12/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class App { 8 | 9 | public static void main(String[] args) throws Exception { 10 | 11 | ExecutorService executor = Executors.newCachedThreadPool(); 12 | 13 | for (int i = 0; i < 200; i++) { 14 | executor.submit(new Runnable() { 15 | public void run() { 16 | Connection.getInstance().connect(); 17 | } 18 | }); 19 | } 20 | 21 | executor.shutdown(); 22 | 23 | executor.awaitTermination(1, TimeUnit.DAYS); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /Thread12/src/demo1/Connection.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.concurrent.Semaphore; 4 | 5 | public class Connection { 6 | 7 | private static Connection instance = new Connection(); 8 | 9 | private Semaphore sem = new Semaphore(10, true); 10 | 11 | private int connections = 0; 12 | 13 | private Connection() { 14 | 15 | } 16 | 17 | public static Connection getInstance() { 18 | return instance; 19 | } 20 | 21 | public void connect() { 22 | try { 23 | sem.acquire(); 24 | } catch (InterruptedException e1) { 25 | e1.printStackTrace(); 26 | } 27 | 28 | try { 29 | doConnect(); 30 | } finally { 31 | 32 | sem.release(); 33 | } 34 | } 35 | 36 | public void doConnect() { 37 | 38 | synchronized (this) { 39 | connections++; 40 | System.out.println("Current connections: " + connections); 41 | } 42 | 43 | try { 44 | Thread.sleep(2000); 45 | } catch (InterruptedException e) { 46 | e.printStackTrace(); 47 | } 48 | 49 | synchronized (this) { 50 | connections--; 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Thread13/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread13/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread13 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread13/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.io.IOException; 4 | import java.util.Random; 5 | import java.util.concurrent.Callable; 6 | import java.util.concurrent.ExecutionException; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | import java.util.concurrent.Future; 10 | 11 | public class App { 12 | 13 | public static void main(String[] args) { 14 | ExecutorService executor = Executors.newCachedThreadPool(); 15 | 16 | Future future = executor.submit(new Callable() { 17 | 18 | @Override 19 | public Integer call() throws Exception { 20 | Random random = new Random(); 21 | int duration = random.nextInt(4000); 22 | 23 | if (duration > 2000) { 24 | throw new IOException("Sleeping for too long."); 25 | } 26 | 27 | System.out.println("Starting ..."); 28 | 29 | try { 30 | Thread.sleep(duration); 31 | } catch (InterruptedException e) { 32 | e.printStackTrace(); 33 | } 34 | 35 | System.out.println("Finished."); 36 | 37 | return duration; 38 | } 39 | 40 | }); 41 | 42 | executor.shutdown(); 43 | 44 | try { 45 | System.out.println("Result is: " + future.get()); 46 | } catch (InterruptedException e) { 47 | e.printStackTrace(); 48 | } catch (ExecutionException e) { 49 | IOException ex = (IOException) e.getCause(); 50 | 51 | System.out.println(ex.getMessage()); 52 | } 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /Thread14/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread14/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread14 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread14/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.Callable; 5 | import java.util.concurrent.ExecutorService; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.Future; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class App { 11 | 12 | public static void main(String[] args) throws InterruptedException { 13 | 14 | System.out.println("Starting."); 15 | 16 | ExecutorService exec = Executors.newCachedThreadPool(); 17 | 18 | Future fu = exec.submit(new Callable() { 19 | 20 | @Override 21 | public Void call() throws Exception { 22 | Random ran = new Random(); 23 | 24 | for (int i = 0; i < 1E8; i++) { 25 | 26 | if (Thread.currentThread().isInterrupted()) { 27 | System.out.println("Interrupted!"); 28 | break; 29 | } 30 | 31 | Math.sin(ran.nextDouble()); 32 | } 33 | return null; 34 | } 35 | 36 | }); 37 | 38 | exec.shutdown(); 39 | 40 | Thread.sleep(500); 41 | 42 | exec.shutdownNow(); 43 | // fu.cancel(true); 44 | 45 | exec.awaitTermination(1, TimeUnit.DAYS); 46 | 47 | System.out.println("Finished."); 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /Thread15/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread15/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread15 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread15/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import javax.swing.SwingUtilities; 4 | 5 | public class App { 6 | 7 | /** 8 | * @param args 9 | */ 10 | public static void main(String[] args) { 11 | SwingUtilities.invokeLater(new Runnable() { 12 | 13 | @Override 14 | public void run() { 15 | new MainFrame("SwingWorker Demo"); 16 | } 17 | }); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /Thread15/src/demo1/MainFrame.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.awt.GridBagConstraints; 4 | import java.awt.GridBagLayout; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.ActionListener; 7 | import java.util.List; 8 | import java.util.concurrent.ExecutionException; 9 | 10 | import javax.swing.JButton; 11 | import javax.swing.JFrame; 12 | import javax.swing.JLabel; 13 | import javax.swing.SwingWorker; 14 | 15 | public class MainFrame extends JFrame { 16 | 17 | private JLabel countLabel1 = new JLabel("0"); 18 | private JLabel statusLabel = new JLabel("Task not completed."); 19 | private JButton startButton = new JButton("Start"); 20 | 21 | public MainFrame(String title) { 22 | super(title); 23 | 24 | setLayout(new GridBagLayout()); 25 | 26 | GridBagConstraints gc = new GridBagConstraints(); 27 | 28 | gc.fill = GridBagConstraints.NONE; 29 | 30 | gc.gridx = 0; 31 | gc.gridy = 0; 32 | gc.weightx = 1; 33 | gc.weighty = 1; 34 | add(countLabel1, gc); 35 | 36 | gc.gridx = 0; 37 | gc.gridy = 1; 38 | gc.weightx = 1; 39 | gc.weighty = 1; 40 | add(statusLabel, gc); 41 | 42 | gc.gridx = 0; 43 | gc.gridy = 2; 44 | gc.weightx = 1; 45 | gc.weighty = 1; 46 | add(startButton, gc); 47 | 48 | startButton.addActionListener(new ActionListener() { 49 | public void actionPerformed(ActionEvent arg0) { 50 | start(); 51 | } 52 | }); 53 | 54 | setSize(200, 400); 55 | setDefaultCloseOperation(EXIT_ON_CLOSE); 56 | setVisible(true); 57 | } 58 | 59 | private void start() { 60 | 61 | // Use SwingWorker and return null from doInBackground if 62 | // you don't want any final result and you don't want to update the GUI 63 | // as the thread goes along. 64 | // First argument is the thread result, returned when processing 65 | // finished. 66 | // Second argument is the value to update the GUI with via publish() and 67 | // process() 68 | SwingWorker worker = new SwingWorker() { 69 | 70 | @Override 71 | /* 72 | * Note: do not update the GUI from within doInBackground. 73 | */ 74 | protected Boolean doInBackground() throws Exception { 75 | 76 | // Simulate useful work 77 | for (int i = 0; i < 30; i++) { 78 | Thread.sleep(100); 79 | System.out.println("Hello: " + i); 80 | 81 | // optional: use publish to send values to process(), which 82 | // you can then use to update the GUI. 83 | publish(i); 84 | } 85 | 86 | return false; 87 | } 88 | 89 | @Override 90 | // This will be called if you call publish() from doInBackground() 91 | // Can safely update the GUI here. 92 | protected void process(List chunks) { 93 | Integer value = chunks.get(chunks.size() - 1); 94 | 95 | countLabel1.setText("Current value: " + value); 96 | } 97 | 98 | @Override 99 | // This is called when the thread finishes. 100 | // Can safely update GUI here. 101 | protected void done() { 102 | 103 | try { 104 | Boolean status = get(); 105 | statusLabel.setText("Completed with status: " + status); 106 | } catch (InterruptedException e) { 107 | e.printStackTrace(); 108 | } catch (ExecutionException e) { 109 | e.printStackTrace(); 110 | } 111 | 112 | } 113 | 114 | }; 115 | 116 | worker.execute(); 117 | } 118 | } -------------------------------------------------------------------------------- /Thread2/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread2/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread2 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread2/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.6 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.6 12 | -------------------------------------------------------------------------------- /Thread2/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.Scanner; 4 | 5 | class Processor extends Thread { 6 | 7 | private volatile boolean running = true; 8 | 9 | public void run() { 10 | 11 | while (running) { 12 | System.out.println("Running"); 13 | 14 | try { 15 | Thread.sleep(50); 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); 18 | } 19 | } 20 | } 21 | 22 | public void shutdown() { 23 | running = false; 24 | } 25 | } 26 | 27 | public class App { 28 | 29 | public static void main(String[] args) { 30 | Processor pro = new Processor(); 31 | pro.start(); 32 | 33 | // Wait for the enter key 34 | new Scanner(System.in).nextLine(); 35 | 36 | pro.shutdown(); 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /Thread3/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread3/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread3 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread3/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.6 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.6 12 | -------------------------------------------------------------------------------- /Thread3/src/demo1/Worker.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | public class Worker { 4 | private int count = 0; 5 | 6 | public synchronized void increment() { 7 | count++; 8 | } 9 | 10 | public static void main(String[] args) { 11 | Worker worker = new Worker(); 12 | worker.run(); 13 | } 14 | 15 | public void run() { 16 | Thread thread1 = new Thread(new Runnable() { 17 | public void run() { 18 | for (int i = 0; i < 10000; i++) { 19 | increment(); 20 | } 21 | } 22 | }); 23 | thread1.start(); 24 | 25 | Thread thread2 = new Thread(new Runnable() { 26 | public void run() { 27 | for (int i = 0; i < 10000; i++) { 28 | increment(); 29 | } 30 | } 31 | }); 32 | thread2.start(); 33 | 34 | try { 35 | thread1.join(); 36 | thread2.join(); 37 | } catch (InterruptedException e) { 38 | e.printStackTrace(); 39 | } 40 | 41 | System.out.println("Count is: " + count); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Thread4/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread4/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread4 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread4/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | public class App { 4 | 5 | public static void main(String[] args) { 6 | Worker worker = new Worker(); 7 | worker.main(); 8 | 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /Thread4/src/demo1/Worker.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Random; 6 | 7 | 8 | public class Worker { 9 | 10 | private Random random = new Random(); 11 | 12 | private Object lock1 = new Object(); 13 | private Object lock2 = new Object(); 14 | 15 | private List list1 = new ArrayList(); 16 | private List list2 = new ArrayList(); 17 | 18 | public void stageOne() { 19 | 20 | synchronized (lock1) { 21 | try { 22 | Thread.sleep(1); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | 27 | list1.add(random.nextInt(100)); 28 | } 29 | 30 | } 31 | 32 | public void stageTwo() { 33 | 34 | synchronized (lock2) { 35 | try { 36 | Thread.sleep(1); 37 | } catch (InterruptedException e) { 38 | e.printStackTrace(); 39 | } 40 | 41 | list2.add(random.nextInt(100)); 42 | } 43 | 44 | } 45 | 46 | public void process() { 47 | for(int i=0; i<1000; i++) { 48 | stageOne(); 49 | stageTwo(); 50 | } 51 | } 52 | 53 | public void main() { 54 | System.out.println("Starting ..."); 55 | 56 | long start = System.currentTimeMillis(); 57 | 58 | Thread t1 = new Thread(new Runnable() { 59 | public void run() { 60 | process(); 61 | } 62 | }); 63 | 64 | Thread t2 = new Thread(new Runnable() { 65 | public void run() { 66 | process(); 67 | } 68 | }); 69 | 70 | t1.start(); 71 | t2.start(); 72 | 73 | try { 74 | t1.join(); 75 | t2.join(); 76 | } catch (InterruptedException e) { 77 | e.printStackTrace(); 78 | } 79 | 80 | long end = System.currentTimeMillis(); 81 | 82 | System.out.println("Time taken: " + (end - start)); 83 | System.out.println("List1: " + list1.size() + "; List2: " + list2.size()); 84 | } 85 | } -------------------------------------------------------------------------------- /Thread5/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread5/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread5 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread5/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | class Processor implements Runnable { 8 | 9 | private int id; 10 | 11 | public Processor(int id) { 12 | this.id = id; 13 | } 14 | 15 | public void run() { 16 | System.out.println("Starting: " + id); 17 | 18 | try { 19 | Thread.sleep(5000); 20 | } catch (InterruptedException e) { 21 | } 22 | 23 | System.out.println("Completed: " + id); 24 | } 25 | } 26 | 27 | public class App { 28 | 29 | public static void main(String[] args) { 30 | 31 | ExecutorService executor = Executors.newFixedThreadPool(2); 32 | 33 | for (int i = 0; i < 5; i++) { 34 | executor.submit(new Processor(i)); 35 | } 36 | 37 | executor.shutdown(); 38 | 39 | System.out.println("All tasks submitted."); 40 | 41 | try { 42 | executor.awaitTermination(1, TimeUnit.DAYS); 43 | } catch (InterruptedException e) { 44 | } 45 | 46 | System.out.println("All tasks completed."); 47 | } 48 | } -------------------------------------------------------------------------------- /Thread6/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread6/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread6 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread6/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | import java.util.concurrent.ExecutorService; 5 | import java.util.concurrent.Executors; 6 | 7 | class Processor implements Runnable { 8 | private CountDownLatch latch; 9 | 10 | public Processor(CountDownLatch latch) { 11 | this.latch = latch; 12 | } 13 | 14 | public void run() { 15 | System.out.println("Started."); 16 | 17 | try { 18 | Thread.sleep(3000); 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | 23 | latch.countDown(); 24 | } 25 | } 26 | 27 | public class App { 28 | 29 | public static void main(String[] args) { 30 | 31 | CountDownLatch latch = new CountDownLatch(3); 32 | 33 | ExecutorService executor = Executors.newFixedThreadPool(3); 34 | 35 | for (int i = 0; i < 3; i++) { 36 | executor.submit(new Processor(latch)); 37 | } 38 | 39 | try { 40 | latch.await(); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } 44 | 45 | System.out.println("Completed."); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Thread7/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread7/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread7 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread7/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.ArrayBlockingQueue; 5 | import java.util.concurrent.BlockingQueue; 6 | 7 | public class App { 8 | 9 | private static BlockingQueue queue = new ArrayBlockingQueue( 10 | 10); 11 | 12 | public static void main(String[] args) throws InterruptedException { 13 | Thread t1 = new Thread(new Runnable() { 14 | public void run() { 15 | try { 16 | producer(); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | } 21 | }); 22 | 23 | Thread t2 = new Thread(new Runnable() { 24 | public void run() { 25 | try { 26 | consumer(); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | } 31 | }); 32 | 33 | t1.start(); 34 | t2.start(); 35 | 36 | t1.join(); 37 | t2.join(); 38 | } 39 | 40 | private static void producer() throws InterruptedException { 41 | Random random = new Random(); 42 | 43 | while (true) { 44 | queue.put(random.nextInt(100)); 45 | } 46 | } 47 | 48 | private static void consumer() throws InterruptedException { 49 | Random random = new Random(); 50 | 51 | while (true) { 52 | Thread.sleep(100); 53 | 54 | if (random.nextInt(10) == 0) { 55 | Integer value = queue.take(); 56 | 57 | System.out.println("Taken value: " + value 58 | + "; Queue size is: " + queue.size()); 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Thread8/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread8/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread8 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread8/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | public class App { 4 | 5 | public static void main(String[] args) throws InterruptedException { 6 | 7 | final Processor processor = new Processor(); 8 | 9 | Thread t1 = new Thread(new Runnable() { 10 | 11 | @Override 12 | public void run() { 13 | try { 14 | processor.produce(); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | } 19 | }); 20 | 21 | Thread t2 = new Thread(new Runnable() { 22 | 23 | @Override 24 | public void run() { 25 | try { 26 | processor.consume(); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | } 31 | }); 32 | 33 | t1.start(); 34 | t2.start(); 35 | 36 | t1.join(); 37 | t2.join(); 38 | } 39 | } -------------------------------------------------------------------------------- /Thread8/src/demo1/Processor.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.Scanner; 4 | 5 | public class Processor { 6 | 7 | public void produce() throws InterruptedException { 8 | synchronized (this) { 9 | System.out.println("Producer thread running ...."); 10 | wait(); 11 | System.out.println("Resumed."); 12 | } 13 | } 14 | 15 | public void consume() throws InterruptedException { 16 | 17 | Scanner scanner = new Scanner(System.in); 18 | Thread.sleep(2000); 19 | 20 | synchronized (this) { 21 | System.out.println("Waiting for return key."); 22 | scanner.nextLine(); 23 | System.out.println("Return key pressed."); 24 | notify(); 25 | Thread.sleep(5000); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Thread9/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Thread9/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Thread9 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Thread9/src/demo1/App.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | public class App { 4 | 5 | public static void main(String[] args) throws InterruptedException { 6 | 7 | final Processor processor = new Processor(); 8 | 9 | Thread t1 = new Thread(new Runnable() { 10 | 11 | @Override 12 | public void run() { 13 | try { 14 | processor.produce(); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | } 19 | }); 20 | 21 | Thread t2 = new Thread(new Runnable() { 22 | 23 | @Override 24 | public void run() { 25 | try { 26 | processor.consume(); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | } 31 | }); 32 | 33 | t1.start(); 34 | t2.start(); 35 | 36 | t1.join(); 37 | t2.join(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Thread9/src/demo1/Processor.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Random; 5 | 6 | public class Processor { 7 | 8 | private LinkedList list = new LinkedList(); 9 | private final int LIMIT = 10; 10 | private Object lock = new Object(); 11 | 12 | public void produce() throws InterruptedException { 13 | 14 | int value = 0; 15 | 16 | while (true) { 17 | 18 | synchronized (lock) { 19 | 20 | while (list.size() == LIMIT) { 21 | lock.wait(); 22 | } 23 | 24 | list.add(value++); 25 | lock.notify(); 26 | } 27 | 28 | } 29 | } 30 | 31 | public void consume() throws InterruptedException { 32 | 33 | Random random = new Random(); 34 | 35 | while (true) { 36 | 37 | synchronized (lock) { 38 | 39 | while (list.size() == 0) { 40 | lock.wait(); 41 | } 42 | 43 | System.out.print("List size is: " + list.size()); 44 | int value = list.removeFirst(); 45 | System.out.println("; value is: " + value); 46 | lock.notify(); 47 | } 48 | 49 | Thread.sleep(random.nextInt(1000)); 50 | } 51 | } 52 | } --------------------------------------------------------------------------------