一run()和start()
这两个方法应该都比较熟悉把需要并行处理的代码放在run()方法中start()方法启动线程将自动调用 run()方法这是由Java的内存机制规定的并且run()方法必须是public访问权限返回值类型为void
二关键字Synchronized
这个关键字用于保护共享数据当然前提是要分清哪些数据是共享数据每个对象都有一个锁标志当一个线程访问该对象时被Synchronized修饰的数据将被上锁阻止其他线程访问当前线程访问完这部分数据后释放锁标志其他线程就可以访问了
public ThreadTest implements Runnable
{
public synchronized void run(){
for(int i=;i<;i++)
{
Systemoutprintln( + i);
}
}
public static void main(String[] args)
{
Runnable r = new ThreadTest();
Runnable r = new ThreadTest();
Thread t = new Thread(r);
Thread t = new Thread(r);
tstart();
tstart();
}
}
以上这段程序中的 i 变量并不是共享数据也就是这里的Synchronized关键字并未起作用因为tt两个线程是两个对象(rr)的线程不同的对象其数据是不同的所以r和r两个对象的i变量是并不是共享数据
当把代码改成如下Synchronized关键字才会起作用
Runnable r = new ThreadTest();
Thread t = new Thread(r);
Thread t = new Thread(r);
tstart();
tstart();
三sleep()
使当前线程(即调用该方法的线程)暂停执行一段时间让其他线程有机会继续执行但它并不释放对象锁也就是如果有Synchronized同步块其他线程仍然不同访问共享数据注意该方法要捕获异常
比如有两个线程同时执行(没有Synchronized)一个线程优先级为MAX_PRIORITY另一个为MIN_PRIORITY如果没有Sleep()方法只有高优先级的线程执行完成后低优先级的线程才能执行但当高优先级的线程sleep()后低优先级就有机会执行了
总之sleep()可以使低优先级的线程得到执行的机会当然也可以让同优先级高优先级的线程有执行的机会
四join()
join()方法使调用该方法的线程在此之前执行完毕也就是等待调用该方法的线程执行完毕后再往下继续执行注意该方法也要捕获异常
五yield()
它与sleep()类似只是不能由用户指定暂停多长时间并且yield()方法只能让同优先级的线程有执行的机会
六wait()和notify()notifyAll()
这三个方法用于协调多个线程对共享数据的存取所以必须在Synchronized语句块内使用这三个方法前面说过Synchronized这个关键字用于保护共享数据阻止其他线程对共享数据的存取但是这样程序的流程就很不灵活了如何才能在当前线程还没退出Synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制
wait()方法使当前线程暂停执行并释放对象锁标志让其他线程可以进入Synchronized数据块当前线程被放入对象等待池中当调用 notify()方法后将从对象的等待池中移走一个任意的线程并放到锁标志等待池中只有锁标志等待池中的线程能够获取锁标志如果锁标志等待池中没有线程则notify()不起作用
notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中