多线程multi-Thread
1 进程:运行中的程序,一个进程可包含多个线程,多个进程间数据和内存资源是独立的。就像一个pdf和一个word两个进程,而word里又可以包含输入线程和打印线程!
2线程:本身不能运行,要位于进程中才可以运行,将所要执行的代码或方法放入线程,通过运行线程而运行代码。线程比进程更轻量级,切换线程时代价比切换进程小,效率高,多个线程间的数据和内存资源是共享的,因此线程间可以通讯。
3多线程:1当一个程序的多段代码需要同时交替执行的时候就需要多线程,让单个程序同时运行多个线程,执行不同的任务,实现并发。2多线程的目的是:最大限度的利用cpu资源,提高cpu利用率。3每个main方法就是jdk默认启动的一个线程,叫主线程main。3一个线程必须要有cpu资源才能执行,一旦一个线程start,就不再受我们控制了,由cpu随机调配线程了,有很强的随机性!!4一个线程只能start启动一次。只能重新new个线程!5 2核cpu最多同时有两个线程执行5Thread的静态sleep方法,Thread.sleep()会使当前线程失去cpu,让其他线程执行。
4多线程实现的两种方式:1继承java.lang.Thread类重写run方法2实现Runnable接口,实现run方法
方式一:继承java.lang.Thread类重写run方法
1例:class ThreadTest extends Thread{
@Override
run(){要执行的代码}}
main(){ThreadTest t=new ThreadTest();t.start();}调用start方法,线程执行!
run方法是由cpu来随机调用的,我们不能调!!!
2例: class ThreadTest2 extends Thread{
@Override
run(){要执行的代码}
main(){ThreadTest t=new ThreadTest();t.start();ThreadTest2 t2=new ThreadTest2();t2.start();}}
两个线程,cpu到底会调用谁,是随机的,不可预测!
3Thread有构造方法:Thread(String name)为线程命名,子类如果想调用父类含参数的构造方法需要用super关键字,并提供子类构造方法:
public ThreadTest(String name){super(name);}
子类就可以:new ThreadTest(“线程名”);
2方式2:实现Runnable接口,实现run方法
1例 1 class ThreadTest implements Runnable{
@Override
run(){要执行的代码}}
2 Thread方法有构造方法:Thread(Runnable target)
main(){Thread t1=new Thread(new ThreadTest()); t1.start();}
2多线程共享公用资源:多个线程公用一个Runnable对象的资源(只是成员变量),不共用局部变量
1class MyThread implements Runnable{int i;
run(){while(true){Thread.sleep(1000); i++; if(50=i){return;}}}}
2 main(){Rnnnable r=new MyThread();只生成一个Runnable对象
Thread t1=new MyThread(r);t1.start();生成两个线程公用一个Runnable对象
Thread t2=new MyThread(r);t2.start();
两个线程会公用一个Runnable对象的成员变量i;
但如果将i改成run方法的局部变量,不会再公用,因为每个线程只要运行方法就会生成i变量,是独立的!!
如果线程不共用Runnable对象,每个线程会有自己独立的Runnable对象的成员变量,不 在共享资源!
共享Runnable对象是共享资源的本质!!
3公用公共资源不只是指传入同一个Runnable对象,也可以公用其他任意类的对象或其属性,和上面公用资源本质一样的:公用同一对象,或者是 类的静态属性,无论多少对象,都只共用一份属性。
class Bank{private int money=1000;Bank对象或money属性是公共资源
public int getMoney(int num){money-=num; return num;}}
class MyThread extends Thread{
private Bank b; 线程操作账户,需要账户对象引用
public Mythread(Bank b){this.b=b}
run(){b.getMoney(800);}}
main(){Bank b=new Bank();
Thread t1=new MyThread(b);t1.start();多个线程会公用同一Bank对象的money属性。
Thread t2=new MyThread(b);t2.start();}
4当不需要多个线程资源共享的话:更好的方式是用匿名内部类,如果参数new的形式传递的话,只用一次。
Thread t1=new Thread(new Runnable{run(){代码}});
main(){ThreadTest t=new ThreadTest();t.start();}
5当线程的run方法里不只是简单代码,而是调用对象或类的成员或方法的时候,线程类里应当定义该对象的成员属性,并定义传入对象引用的构造方法,从而可以引用,如上例!
class MyThread extends Thread{
private Bank b; 线程操作账户,需要账户对象引用
public Mythread(Bank b){this.b=b}
|