启动线程两种方式:
1. 实现Runnable接口;
2. 继承Thread类。
选用:能使用接口,就不用从Thread类继承。
使用继承的方法不够灵活,从这个类继承了就不能从其他类继承;
实现接口后,还可以从其他类继承,也可以再实现其他接口。
线程状态转换:
常用方法:
join() Waits for this thread to die.合并到当前线程执行,类似于方法调用了。
yield()
A hint to the scheduler that the current thread is willing to yield its current use of a processor. 让出CPU,给其他线程执行机会。
setPriority(int newPriority) Changes the priority of this thread.
关闭线程
stop() Deprecated. This method is inherently unsafe.
Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack).
If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running.
The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running.
If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.
For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.
举例:
public class TestThread4 { public static void main(String args[]){ Runner4 r = new Runner4(); Thread t = new Thread(r); t.start(); for(int i=0;i<100000;i++){ if(i%10000==0 & i>0) System.out.println("in thread main i=" + i); } System.out.println("Thread main is over"); r.shutDown();//关闭线程推荐方法。flag=false,run方法结束、线程结束。 //t.stop(); stop方法已废弃, } } class Runner4 implements Runnable { private boolean flag=true; public void run() { int i = 0; while (flag==true) { System.out.print(" " + i++); } } public void shutDown() { flag = false; } }
多线程同步
一般而言,需要同步的对象,在改的相关方法上加锁(两个方法都修改了同样的值,两个方法都加同步),读时不加锁(允许多个线程同时读)。
syschronized
对象的互斥锁标记,保证在任一时刻,只能有一个线程访问该对象。
关键字synchronized与互斥锁联系。
wait()
发生一个阻塞事件。
public final void wait() throws InterruptedExceptionCauses the current thread to wait until another thread invokes the notify() method or the notifyAll() method
for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
与sleep区别:
- wait时其他线程可以访问锁定对象;(故调用wait方法时必须锁定该对象。)
- sleep时别的线程不能访问。
notifiy()/notifyAll()
叫醒某一个/所有 wait在某个对象上的线程。
public final void notify()
Wakes up a single thread that is waiting on this object's monitor.
If any threads are waiting on this object, one of them is chosen to be awakened.
The choice is arbitrary and occurs at the discretion of the implementation.
A thread waits on an object's monitor by calling one of the wait methods.
生产者消费者模式
public class ProducerConsumer { public static void main(String[] args) { SyncStack ss = new SyncStack(); Producer p = new Producer(ss); Consumer c = new Consumer(ss); new Thread(p).start(); new Thread(p).start(); new Thread(p).start(); new Thread(c).start(); } } class WoTou { int id; WoTou(int id) { this.id = id; } public String toString() { return "WoTou : " + id; } } class SyncStack { int index = 0; WoTou[] arrWT = new WoTou[6]; public synchronized void push(WoTou wt) { while(index == arrWT.length) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); arrWT[index] = wt; index ++; } public synchronized WoTou pop() { while(index == 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); index--; return arrWT[index]; } } class Producer implements Runnable { SyncStack ss = null; Producer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { WoTou wt = new WoTou(i); ss.push(wt); System.out.println("生产了:" + wt); try { Thread.sleep((int)(Math.random() * 200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { SyncStack ss = null; Consumer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { WoTou wt = ss.pop(); System.out.println("消费了: " + wt); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } }