Java学习笔记-多线程
2015-02-14 01:01
363 查看
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
进程:正在执行中的一个程序。
线程:是一个正在执行的程序,进程中一个独立的控制单元。线程控制着进程的执行。
多线程:多线程的出现能让程序产生同时运行效果。可以提高程序执行效率。
线程状态:创建状态--->运行状态--->临时状态(具备执行资格,但没有执行权)----->冻结状态(放弃执行资格,进入临时状态)------>消亡状态。
创建线程方法:
1.继承Thread类,覆写run方法。
代码示例:
注意:启动线程必须用start方法,如果直接调用run方法,该线程并没有启动,相当于单线程,程序会按顺序执行。
2.实现Runnable,覆写run方法。
(1)已经有了Thread类为什么还要有Runnable接口:继承只能是单继承,如果一个类已经继承了其他类但是还有代码需要多线程执行,这时就没办法再继承Thread类(单继承Java不允许多继承,但可以通过实现接口,扩展功能)
(2)实现Runnable接口和继承Thread类的区别:
实现Runnable的好处:避免了继承的局限性。资源可以共享
继承Thread类线程代码存放在Thread子类的run方法中。
实现Runnable接口线程代码存放在接口子类的run方法中。
代码示例:
3.多线程安全:
当多线程操作共享数据时(多条语句),一个线程执行了一部分的语句,还没执行完,另一个线程参与执行,这样就会导致数据错乱,会出现安全问题。
同步可以解决多线程的安全问题:加同步后一个线程执行的时候会先拿到锁,当只执行完后以后会释放锁,下一个线程拿到锁才可以执行同步内的代码。
同步的前提:
(1)必须要有两个或两个以上的线程,
(2)必须多个线程使用同一个锁。
同步好处:解决线程的安全问题。
同步弊端:多线程需要判断锁,较为消耗资源。
同步代码块:自己需要指定一个锁。
代码示例:
同步函数:使用本类对象的锁(this)
静态同步函数:使用的是所在类的字节码文件对象(类名.class)
4.线程间的通信:安全问题:
注意:两个线程同时操作一个资源,对资源来说就是多线程,所以两个函数里的代码都需要同步,而且必须得用同一个锁。
5.等待唤醒机制:wait,notify;
注意:这里只有两个线程,每次唤醒都是对方。代码可以优化,在资源里设置赋值方法和取出方法,同步赋值和取出方法,同时实现等待唤醒机制,再线程代码里直接调用这两个方法就可以
await()
signal()
signalAll()
Lock替代了synchronized;更好的解决了唤醒对方的问题。
解决了线程的唤醒不能唤醒对方的问题。
代码示例:
7.中断线程,interrupt()
线程处于中断状态而又无法被唤醒时,interrupt可以强制清除中断状态。但会抛异常。
8.守护线程:setDeamon()
线程启动前标记为守护线程,当前台没有线程是,守护线程会自动结束。
9.join
特点:当A线程执行到了B线程的join方法时,A线程就会等待,等B线程运行结束后,A线程才会运行。
join可以临时加入线程执行。
10.线程优先级
setPriority()设置线程优先级,默认都是5,只有1-10. MAX_PRIORITY(10) MIN_PRIORITY(1) NORM_PRIORITY(5).
11.yield 暂停当前正在执行的线程对象,并执行其他线程。
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
进程:正在执行中的一个程序。
线程:是一个正在执行的程序,进程中一个独立的控制单元。线程控制着进程的执行。
多线程:多线程的出现能让程序产生同时运行效果。可以提高程序执行效率。
线程状态:创建状态--->运行状态--->临时状态(具备执行资格,但没有执行权)----->冻结状态(放弃执行资格,进入临时状态)------>消亡状态。
创建线程方法:
1.继承Thread类,覆写run方法。
代码示例:
package ThreadDemo; public class ThreadTest { public static void main(String [] args){ Demo d = new Demo();//创建Demo对象,因为Demo继承了Thread所以创建Demo对象也是创建了一个线程。 d.start();//start方法启动线程,并调用run方法 for(int i=0;i<60;i++){ System.out.println("main....run"+i); } } } class Demo extends Thread{//继承Thread类; @Override public void run(){//覆写run方法,run方法里存放线程执行的代码。 for(int x=0;x<60;x++){ System.out.println("demo....run"+x); } } }
注意:启动线程必须用start方法,如果直接调用run方法,该线程并没有启动,相当于单线程,程序会按顺序执行。
2.实现Runnable,覆写run方法。
(1)已经有了Thread类为什么还要有Runnable接口:继承只能是单继承,如果一个类已经继承了其他类但是还有代码需要多线程执行,这时就没办法再继承Thread类(单继承Java不允许多继承,但可以通过实现接口,扩展功能)
(2)实现Runnable接口和继承Thread类的区别:
实现Runnable的好处:避免了继承的局限性。资源可以共享
继承Thread类线程代码存放在Thread子类的run方法中。
实现Runnable接口线程代码存放在接口子类的run方法中。
代码示例:
package ThreadDemo; public class ThreadTest1 { public static void main(String [] args){ TicketDemo td= new TicketDemo(); new Thread(td).start();//创建线程,接受一个Runnable接口的子类,并启动线程 new Thread(td).start(); new Thread(td).start(); new Thread(td).start(); } } class TicketDemo implements Runnable{//实现Runnable接口 private int ticket=100; @Override public void run(){//覆写run方法。 while(true){ if(ticket>0) System.out.println(Thread.currentThread().getName()+"...sale"+ticket--); } } }
3.多线程安全:
当多线程操作共享数据时(多条语句),一个线程执行了一部分的语句,还没执行完,另一个线程参与执行,这样就会导致数据错乱,会出现安全问题。
同步可以解决多线程的安全问题:加同步后一个线程执行的时候会先拿到锁,当只执行完后以后会释放锁,下一个线程拿到锁才可以执行同步内的代码。
同步的前提:
(1)必须要有两个或两个以上的线程,
(2)必须多个线程使用同一个锁。
同步好处:解决线程的安全问题。
同步弊端:多线程需要判断锁,较为消耗资源。
同步代码块:自己需要指定一个锁。
代码示例:
Object obj = new Object(); private int sum=0; public void add(int n){ synchronized(obj){ sum=sum+n; System.out.println(sum); } }
同步函数:使用本类对象的锁(this)
private int sum=0; public synchronized void add(int n){ sum=sum+n; System.out.println(sum); }
静态同步函数:使用的是所在类的字节码文件对象(类名.class)
class bank{ private static int sum=0; public static synchronized void add(int n){ sum=sum+n; System.out.println(sum); } }
4.线程间的通信:安全问题:
注意:两个线程同时操作一个资源,对资源来说就是多线程,所以两个函数里的代码都需要同步,而且必须得用同一个锁。
package Thread; public class InputOutpuDemo { public static void main(String [] args){ Res r = new Res(); Input in = new Input(r); Output out = new Output(r); new Thread(in).start();//创建线程传入存入的对象,启动线程。 new Thread(out).start(); } } class Res{//共享资源 String name; String sex; boolean flag; } class Input implements Runnable{//实现runnable接口 private Res r; Input(Res r){//定义构造函数接收共享资源 this.r=r; } @Override public void run(){//覆写run方法 int x=0; while(true){ synchronized(r){//构造代码块使用的是共同资源对象 if(x==0){ r.name="mike"; r.sex="man"; } else{ r.name="丽丽"; r.sex="女女女女"; } x=(x+1)%2;//切换存入数据 } } } } class Output implements Runnable{//实现runnable接口 private Res r; Output(Res r){//接收共同资源 this.r=r; } @Override public void run(){//覆写run方法 while(true){ synchronized(r){//同步代码块,跟存入的代码都需要同步,使用同一个锁 System.out.println(r.name+"..."+r.sex); } } } }
5.等待唤醒机制:wait,notify;
注意:这里只有两个线程,每次唤醒都是对方。代码可以优化,在资源里设置赋值方法和取出方法,同步赋值和取出方法,同时实现等待唤醒机制,再线程代码里直接调用这两个方法就可以
package Thread; public class InputOutpuDemo { public static void main(String [] args){ Res r = new Res();//创建资源对象 Input in = new Input(r); Output out = new Output(r); new Thread(in).start();//创建线程,并启动线程 new Thread(out).start(); } } class Res{ String name; String sex; boolean flag;//定义标记达到存一次取一次的目的,不会乱 } class Input implements Runnable{//实现runnable接口 private Res r; Input(Res r){//构造函数接收共享资源 this.r=r; } @Override public void run(){//覆写run方法 int x=0; while(true){ synchronized(r){//同步代码块,解决程序的安全问题 if(r.flag)//flag默认为flase,条件为假,跳过wait向下执行 try { wait();//会抛异常需要处理 } catch (InterruptedException e) { e.printStackTrace(); } if(x==0){//定义条件循环添加元素 r.name="mike";//给共享资源属性赋值,也就是存入数据 r.sex="man"; } else{ r.name="丽丽"; r.sex="女女女女"; } x=(x+1)%2; r.flag=true;//执行一次将条件改为true,让线程等待,等待前唤醒线程池里的线程 notify(); } } } } class Output implements Runnable{//实现runnable接口 private Res r; Output(Res r){//构造函数接收共享资源 this.r=r; } @Override public void run(){//覆写run方法 while(true){ synchronized(r){//同步代码块 if(!r.flag)//条件为假(flase)等待,上一个线程已经讲条件改为true,跳过等待向下执行 try { wait(); } catch (InterruptedException e) {//处理异常 e.printStackTrace(); } System.out.println(r.name+"..."+r.sex); r.flag=false;//执行完更改条件让线程等待,等待前唤醒线程池里的线程。 notify(); } } } }
<strong>6.JDK1.5以后出现了Condition接口。替代了Object的wait(),notify,notifyAll();</strong>
await()
signal()
signalAll()
Lock替代了synchronized;更好的解决了唤醒对方的问题。
解决了线程的唤醒不能唤醒对方的问题。
代码示例:
package ThreadDemo; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ThreadLock { public static void main(String [] args){ Stroage st =new Stroage(); new Thread(new Input1(st)).start();//创建线程, new Thread(new Input1(st)).start(); new Thread(new Input1(st)).start(); new Thread(new Output1(st)).start(); new Thread(new Output1(st)).start(); new Thread(new Output1(st)).start(); } } class Stroage{ private int [] cells=new int [10];//定义数组,存储元素 private int inpos,outpos;//定义角标 private boolean flag; private Lock lock = new ReentrantLock();//创建锁对象,lock是接口只能用子类创建对象 private Condition condition_in=lock.newCondition();//创建两个condition对象,condition是接口可以用lock.newCondition创建,一个用于存入一个用于输出,这样可以只唤醒对方线程。 private Condition condition_out=lock.newCondition(); public void put(int num){//定义存数据的方法 lock.lock();//获取所 while(flag) try { condition_in.await();//condition等待方法替代了Object的wait方法,本方等待。 } catch (InterruptedException e) { e.printStackTrace(); } cells[inpos]=num++; System.out.println("在clles["+inpos+"]中存入数据--"+cells[inpos]); inpos++; if(inpos==cells.length) inpos=0; flag=true; condition_out.signal();//唤醒对方线程; lock.unlock();//释放锁。 } public void out(){//定义取出数据的方法。 lock.lock();//获取锁 while(!flag) try { condition_out.await();//本方等待, } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("从cells["+outpos+"]中取出数据"+cells[outpos]); outpos++; if(outpos==cells.length) outpos=0; flag=false; condition_in.signal();//唤醒对方线程 lock.unlock();//释放锁 } } class Input1 implements Runnable{//实现Runnable接口 private Stroage st; private int num; Input1(Stroage st){ this.st=st; } @Override public void run(){//覆写run方法 while(true){ st.put(num++); } } } class Output1 implements Runnable{//实现Runnable接口 private Stroage st; Output1(Stroage st){ this.st=st; } @Override public void run(){//覆写run方法 while(true){ st.out(); } } }
7.中断线程,interrupt()
线程处于中断状态而又无法被唤醒时,interrupt可以强制清除中断状态。但会抛异常。
8.守护线程:setDeamon()
线程启动前标记为守护线程,当前台没有线程是,守护线程会自动结束。
9.join
特点:当A线程执行到了B线程的join方法时,A线程就会等待,等B线程运行结束后,A线程才会运行。
join可以临时加入线程执行。
10.线程优先级
setPriority()设置线程优先级,默认都是5,只有1-10. MAX_PRIORITY(10) MIN_PRIORITY(1) NORM_PRIORITY(5).
11.yield 暂停当前正在执行的线程对象,并执行其他线程。
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
相关文章推荐
- java多线程学习笔记3
- JAVA多线程学习笔记
- 学习笔记 java多线程 信号量(Semaphore),死锁
- Java学习笔记(多线程)
- Java多线程学习笔记
- JAVA学习笔记之多线程
- 学习java多线程的笔记4--传智播客_张孝祥_空中网挑选实习生的面试题(来源于视频)
- JAVA多线程学习笔记—1
- 学习笔记 java多线程(四)线程间协作
- JAVA学习笔记————多线程
- [零散篇]Java学习笔记---Java的Socket网络编程以及多线程
- 学习java多线程的笔记1--Thread(Runnable t)与重写run()方法等
- Java学习笔记---多线程
- Java学习笔记9——多线程
- Java多线程学习笔记1
- Java 多线程编程 学习笔记
- 黑马程序员java学习笔记之四(java多线程总结)
- 黑马程序员---java多线程 学习笔记
- 学习笔记 - java.util.concurrent 多线程框架(引)
- java学习笔记1017---多线程