最近学习了一下java的多线程,有些许收获,综合记录下来,旨在通过学习和修改简单的小例子了解一个特定的概念。
关于SwingUtilities.invokeLater 和 invokeAndWait方法,
原来使用invokeLater总是以为新开了一个线程,查看了相关资料才发现我错了,这两个方法都是将要执行的代码(run方法内)放到事件分发队列中等待时机运行,具体分析见代码注释。
import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; /** * invokeLater()方法和invokeAndWait()方法区别: * later 方法会在未来某个时间点上异步运行,不知道其何时才会真正的运行 * wait 方法是同步的,它会等到目标完成执行动作后才返回。其不可再事件派发Thread所调用, * 如果thread在事件派发thread运行目标前被中断,则抛出异常。 * 一般法则:使用wait方法读取Swing组件的值或确保继续运行程序之前某些事物应该显示在屏幕上。 * */ public class SwingUtilitiesTest extends JFrame{ JButton testButton = null; public SwingUtilitiesTest(){ init(); } /** * @param args */ public static void main(String[] args) { new SwingUtilitiesTest(); } public void init(){ this.setSize(new Dimension(300,300)); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); testButton = new JButton("test"); testButton.addActionListener(new TestAction()); this.add(testButton); this.setVisible(true); } /** * update text at Event Dispatch Thread * */ public void setButtonText(final String text){ SwingUtilities.invokeLater(new Runnable(){ public void run(){ testButton.setText(text); } }); } int i=0; class TestAction implements ActionListener{ public void actionPerformed(ActionEvent e) { setButtonText("before sleep"); System.out.println("before"); Thread t = new Thread(){ @Override public void run(){ try { System.out.println("before t"); Thread.sleep(5000);//operate which can take a long time setButtonText("after thread sleep"+i++); } catch (InterruptedException e1) { e1.printStackTrace(); } } }; t.start(); setButtonText("after test"+i++); } } }
有关同步,wait 和 notify,
public class WaitTest { int share = 0; Object lock = new Object(); boolean canBRun = false; ThreadA a = null; ThreadB b = null; public WaitTest() { a = new ThreadA(); b = new ThreadB(); b.start(); a.start(); } public static void main(String[] args) { new WaitTest(); } class ThreadA extends Thread { @Override public void run() { synchronized(lock){ for (int i = 0; i < 5; i++) { share++; System.out.println("A thread share : " + share); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } canBRun = true; lock.notify(); } } } class ThreadB extends Thread { @Override public void run() { synchronized(lock){ while(true){ if(canBRun){ for (int i = 0; i < 5; i++) { share++; System.out.println("B thread share : " + share); } break; }else{ try { System.out.println("B wait"); lock.wait();//wait can free lock } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); break; } } } } } } }
有关join方法
public class JoinTest { volatile int share = 0; ThreadA a; ThreadB b; public JoinTest(){ a = new ThreadA(); b = new ThreadB(); a.start(); b.start(); } public static void main(String[] args) { new JoinTest(); } class ThreadA extends Thread{ @Override public void run(){ for(int i = 0; i<5; i++){ share++; System.out.println("A thread share : "+share); try { System.out.println("before b join ,thread a,b is uncontrollable"); if(b.isAlive()){ b.join();// if b join b must run until to the end then a can continue System.out.println("after b join"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class ThreadB extends Thread{ @Override public void run(){ for(int i = 0; i<5; i++){ try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } share++; System.out.println("B thread share : "+share); } } } }
Executors
public class ExecutorsTest1 { volatile int share = 0; ThreadA a; ThreadB b; public ExecutorsTest1(){ // //创建一个可重用固定线程数的线程池 // ExecutorService pool = Executors.newFixedThreadPool(3); // //创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。 // ExecutorService pool = Executors.newCachedThreadPool(); //创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。 ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor(); a = new ThreadA(); b = new ThreadB(); pool.execute(a); pool.execute(b); pool.shutdown(); // a.start(); // b.start(); } public static void main(String[] args) { new ExecutorsTest1(); } class ThreadA extends Thread{ @Override public void run(){ for(int i = 0; i<5; i++){ share++; System.out.println("A thread share : "+share); } } } class ThreadB extends Thread{ @Override public void run(){ for(int i = 0; i<5; i++){ share++; System.out.println("B thread share : "+share); } } } }