一 、线程的理解
1. 线程是系统调度中最小的单位,因为其拥有比进程更小的资源消耗,因此,在进行同类事情,需要进行交互的通讯时,都采用线程来进行处理。就像QQ聊天,打开一个聊 天 窗口 就是一个线程。
2. 多线程是否就没有存在的意义了呢?答案当然不是的。多线程还是有存在的价值的,我们在写输入流输出流,写网络程序等等的时候,都会出现阻塞的情况,如果说,我们 不使用多线程的话,从A中读数据出来的时候,A因为没有准备好,而整个程序阻塞了,其他的任何事情都没法进行。如果采用多线程的话,你就不用担心这个问题了。还举个例 子:游戏中,如果A角色和B角色采用同一个线程来处理的话,那么,很有可能就会出现只会响应A角色的操作,而B角色就始终被占用了的情况,这样,玩起来肯定就没劲了。
因此,线程是有用的,但也不是随便乱用,乱用的话,可能造成性能的低下,它是有一点的适用范围的,一般我认为:需要响应多个人的事情,从设计上需要考虑同时做一些 事情(这些事情很多情况下可能一点关系都没有,也有可能有一些关系的)。
3. 使用多线程的时候,如果某些线程之间涉及到资源共享、互相通讯等等问题的时候,一定得注意线程安全的问题,根据情况看是不是需要使用synchronized关键字。
二、java中使用线程
1、创建线程
eg1:继承Thread
class MyThread extends Thread{
@Override
public void run() {
//code
}
}
启动线程方法:new MyThread().start();
eg2:实现Runnable接口
class MyRunnable implements Runnable {
@Override
public void run() {
//code
}
}
启动线程方法:new Thread(new MyRunnable()).start();
2、设置线程优先级
Thread t = new Thread(myRunnable);
t.setPriority(Thread.MAX_PRIORITY);
t.start();
3.join方法:假如你在A线程中调用了B线程的join方法B.join();,这时B线程继续运行,A线程停止(进入阻塞状态)。等B运行完毕A再继续运行。
sleep方法:线程中调用sleep方法后,本线程停止(进入阻塞状态),运行权交给其他线程。
yield方法:线程中调用yield方法后本线程并不停止,运行权由本线程和优先级不低于本线程的线程来抢。(不一定优先级高的能先抢到,只是优先级高的抢到的时间长)
4、线程同步synchronized
5、wait、notify、notifyAll的用法
wait方法:当前线程转入阻塞状态,让出cpu的控制权,解除锁定。
notify方法:唤醒因为wait()进入阻塞状态的其中一个线程。
notifyAll方法: 唤醒因为wait()进入阻塞状态的所有线程。
这三个方法都必须用synchronized块来包装,而且必须是同一把锁,不然会抛出java.lang.IllegalMonitorStateException异常。
6、结束线程(修改标示符flag为false来终止线程的运行)
三、下面是个小例子:
模拟银行存款情况:
Bank.java
package ytu.edu.com;
public class Bank implements Runnable{
int money=200;
public void setMoney(int n){
money=n;
}
public void run(){
if(Thread.currentThread().getName().equals("会计")){
saveOrTake(300);
}
else if (Thread.currentThread().getName().equals("出纳")){
saveOrTake(150);
}
}
public synchronized void saveOrTake(int amount){
if(Thread.currentThread().getName().equals("会计")){
for(int i=0;i<3;i++){
money=money+amount/3;
System.out.println(Thread.currentThread().getName()+"存入"+amount/3+"账户上有"+money+"休息一会在存。。。");
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
}
}
else if (Thread.currentThread().getName().equals("出纳")){
for(int i=0;i<3;i++){
money=money-amount/3;
System.out.println(Thread.currentThread().getName()+"存入"+amount/3+"账户上有"+money+"休息一会在存。。。");
try {
Thread.sleep(1000);
}catch(InterruptedException e){}
}
}
}
}
测试类 test.java
package ytu.edu.com;
public class test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Bank bank=new Bank();
bank.setMoney(200);
Thread accountant,cashier;
accountant=new Thread(bank);
cashier=new Thread(bank);
accountant.setName("会计");
cashier.setName("出纳");
accountant.start();
cashier.start();
}
}
运行结果: