1.创建和启动线程
线程类必须实现Runnable接口或者扩展Thread类,并且实现run方法,run方法没有参数没有返回值不允许抛出异常。调用start实例方法启动一个线程。调用该方法后,线程准备启动,只有获得CPU时,start将自动调用run,线程才真正启动。
public class DefineThread { /** * 通过继承java.lang.Thread类定义线程 */ class ThreadA extends Thread{ /** * 当线程被运行时调用此方法 */ public void run(){ System.out.println("ThreadA begin,"); System.out.println("ThreadA end."); } } /** * 通过实现java.lang.Runnable接口定义线程 */ class ThreadB implements Runnable{ public void run(){ System.out.println("ThreadB begin,"); System.out.println("ThreadB end."); } } public static void main(String[] args) { DefineThread test = new DefineThread(); //线程的运行具有不确定性,先启动的线程不一定先运行,取决于虚拟机。 Thread threadA = test.new ThreadA(); Runnable tb = test.new ThreadB(); Thread threadB = new Thread(tb); threadA.start(); threadB.start(); } }
2.停止线程
为线程设置一个布尔属性,表示线程是否运行,在run方法中适当地检测标志位,为true时继续运行,需要停止线程时设置标志位为false。
class MyThread extends Thread { private boolean running = false; public void start() { running = true; super.start(); } public void run() { try { while(running) { System.out.println("mythread is running"); Thread.sleep(200); } }catch(InterruptedException e){ } System.out.println("mythread stop."); } public void stopMyThread() { running = false; } } public class ThreadStop { public static void main(String[] args) { MyThread mt = new MyThread(); mt.start(); try{ Thread.sleep(2000); }catch(InterruptedException e){ } mt.stopMyThread(); } }
在类的方法声明中使用synchronized可以保证在同一时刻只有一个线程能够进入该方法。
public class ThreadSynchronized { public synchronized void synchronizedMethod() { System.out.println("Thread in method is:" + Thread.currentThread().getName()); System.out.println("other thread can't enter the method now."); try{ Thread.sleep(5000); }catch(InterruptedException e){ } System.out.println(Thread.currentThread().getName() + " have done its work, leaving method."); } public static void main(String[] args){ final ThreadSynchronized obj = new ThreadSynchronized(); Thread thread1 = new Thread() { public void run() { obj.synchronizedMethod(); } }; Thread thread2 = new Thread() { public void run() { obj.synchronizedMethod(); } }; thread1.start(); try{ Thread.sleep(100); }catch(InterruptedException e){ } thread2.start(); } }
4.线程协作
在synchronized代码块中使用wait方法,能够使当前线程进入等待状态,并释放当前线程拥有的对象锁。在synchronized代码块中使用notify或者notifyAll方法,当前线程释放对象锁,唤醒其它等待该对象锁的线程。当有多个线程都在等待该对象锁时,由虚拟机决定被唤醒的线程。
class CubbyHole { private Object slot; public CubbyHole() { slot = null; } public synchronized void putIn(Object obj) throws InterruptedException{ System.out.println(Thread.currentThread().getName() + "want to putin a object"); while(slot != null){ System.out.println("cubbyhole is full, need to wait."); wait(); System.out.println(Thread.currentThread().getName() + "wake up!"); } slot = obj; System.out.println("fill a object, notify others."); notifyAll(); } public synchronized Object takeOut()throws InterruptedException { System.out.println(Thread.currentThread().getName() + "want to takeout an object."); while(slot == null){ System.out.println("the cubbyhole is empty, need to wait"); wait(); System.out.println(Thread.currentThread().getName() + "wake up!"); } Object obj = slot; slot = null; System.out.println("clear the cubbyhole, notify others."); notifyAll(); return obj; } } public class CubbyHoleMain { public static void main(String[] args){ final CubbyHole ch = new CubbyHole(); Runnable runA = new Runnable() { public void run() { try{ String str; Thread.sleep(500); for(int i = 1; i < 11; i++){ str = "multithread" + i; ch.putIn(str); System.out.println(Thread.currentThread().getName() + " putin ' " + str + " ' "); } /*str = "programming"; ch.putIn(str); System.out.println(Thread.currentThread().getName() + " putin ' " + str + " ' "); str = "with java"; ch.putIn(str); System.out.println(Thread.currentThread().getName() + " putin ' " + str + " ' ");*/ }catch(InterruptedException e){ e.printStackTrace(); } } }; Runnable runB = new Runnable() { public void run() { try{ Object obj; obj = ch.takeOut(); System.out.println(Thread.currentThread().getName() + "takeout ' " + obj + " ' "); Thread.sleep(500); for(int i = 0; i < 9; i++){ obj = ch.takeOut(); System.out.println(Thread.currentThread().getName() + "takeout ' " + obj + " ' "); } /* obj = ch.takeOut(); System.out.println(Thread.currentThread().getName() + "takeout ' " + obj + " ' ");*/ }catch(InterruptedException e){ e.printStackTrace(); } } }; Thread threadA = new Thread(runA, "threadA"); Thread threadB = new Thread(runB, "threadB"); threadA.start(); threadB.start(); } }
5.线程优先级
Java线程优先级分为10个级别,数字越大级别越高,默认为5级。Thread.MAX_PRIORITY和Thread.MIN_PRIORTY和Thread.NORM_PRIORTY是Thread的3个static final成员,分别是10,1,5。
public class Priority { static class MyThread extends Thread{ private int ID = 0; public MyThread(int id){ this.ID = id; } public void run(){ System.out.println("MyThread-" + this.ID + " begin! Priority: " + this.getPriority()); System.out.println("MyThread-" + this.ID + " end!"); } } public static void main(String[] args) { //建立3个优先级不同的线程 MyThread[] myThreads = new MyThread[3]; for (int i=0; i<3; i++){ myThreads[i] = new MyThread(i+1); //三个线程的优先级分别是1,4,7 myThreads[i].setPriority(i*3+1); } //按优先级从低到高启动线程 for (int i=0; i<3; i++){ myThreads[i].start(); } //先启动的线程不一定先运行,虚拟机会考虑线程的优先级,同等情况下,优先级高的线程先运行 } }