(黑马程序员)学习笔记,多线程(一)

来源:互联网 发布:基金定投算法 编辑:程序博客网 时间:2024/06/06 04:05

什么是进程?每一个正在系统上运行的程序都是一个进程,是资源分配的基本单位,也是抢占处理机的调度单位。通常一个进程中包含一个或多个线程。

什么是线程?线程是程序中一个单一的顺序控制流程,与资源分配无关,它属于某一个进程,与进程内的其他线程共享进程的资源。


下面开始创建线程:

1.继承Thread类来创建线程

package thread;public class ThreadTest1 {public static void main(String[] args) {Thread1 t1 = new Thread1("t1");Thread1 t2 = new Thread1("t2");t1.run();//只是调用run()方法,没有启动多线程t2.start();//开启多线程方法for(int i=0;i<60;i++){System.out.println("main..."+i);}}}//写线程就要继承线程类Thread,并重写run()方法class Thread1 extends Thread{public Thread1(String name){super(name);System.out.println(Thread.currentThread().getName()+"创建完成");}//必须重写的方法,以实现自己在线程中的动作,用start()调用public void run(){for(int i=0;i<60;i++){System.out.println(this.getName()+"thread..."+i);}}}

2.实现Runnable接口

package thread;public class ThreadTest2 {public static void main(String[] args) {Thread2 t2 = new Thread2();//创建Runnable对象Thread t = new Thread(t2);//在创建线程时,加入Runnable对象t.start();//开启线程//为了区分Thread2线程,给主线程添加些内容for(int i=0;i<60;i++){System.out.println("main..."+i);}}}//线程也可以通过实现Runnable接口,重写run()方法class Thread2 implements Runnable{//重写Run()方法,以实现自己在线程中的动作,用start()调用public void run(){for(int i=0;i<60;i++){System.out.println(Thread.currentThread().getName()+"thread..."+i);}}}
这两种方式都可以成功创建线程,但还是推荐第二种方式,因为java是单继承的语言,也就是说一旦继承了Thread类,就无法在继承其他的类,这样不利于代码的灵活性。
多线程可以通过锁(synchronized)来控制让其交替运行:

package thread;/** * 多线程交替运行,同步锁 * @author asus *冻结线程wait(), 唤醒等待线程notify(), 唤醒所有等待线程notifyall() */public class InputOutputDemo {public static void main(String[] args) {Ren r = new Ren();Input in = new Input(r);Output out = new Output(r);Thread t1 = new Thread(in);Thread t2 = new Thread(out);t1.start();t2.start();}}//封装对象class Ren{String name = null;String sex = null;boolean flag = false;}//输入class Input implements Runnable{private Ren r;//创建Input对象时获取共有资源Input(Ren r){this.r = r;}public void run(){int b = 0;//使用while循环不断地存入数据while(true){//同步锁,使存入和输出同步synchronized(r){//标志位,true表示完成存入数据,false表示完成输出数据if(r.flag){try {r.wait();//冻结线程} catch (InterruptedException e) {e.printStackTrace();}}//根据b值的不同存入不同的数据if(b==0){r.name = "A";r.sex = "male";}else{r.name = "B";r.sex = "female";}b=(b+1)%2;r.flag = true;r.notify();//唤醒等待线程}}}}//输出class Output implements Runnable{private Ren r;//创建Output对象时获取共有资源Output(Ren r){this.r = r;}public void run(){//使用while循环不断地存入数据while(true){//同步锁,使存入和输出同步synchronized(r){//标志位,true表示完成存入数据,false表示完成输出数据if(!r.flag){try {r.wait();//冻结线程} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(r.name+"..."+r.sex);r.flag = false;r.notify();//唤醒等待线程}}}}
当然多个同步锁有时候也会造成死锁
package thread;/** * 这是一个死锁程序:当线程中含有多个锁的时候,就有可能出现死锁现象,即每一个线程持有对方的锁且不被释放 * @author asus * */public class LockDemo {public static void main(String[] args) {//创建对象并传入标志位Lock l1 = new Lock(true);Lock l2 = new Lock(false);//创建线程Thread t1 = new Thread(l1);Thread t2 = new Thread(l2);//开启线程t1.start();t2.start();}}//提供锁对象class MyLock{static Object lockA = new Object();static Object lockB = new Object();}//多线程死锁class Lock implements Runnable {private boolean flag;Lock(boolean flag) {this.flag = flag;}//当两个或多个线程持有对方同步锁并且不释放,就会出现死锁现象public void run() {if(flag){//使用A锁同步synchronized(MyLock.lockA){System.out.println("if A");//使用B锁同步synchronized(MyLock.lockB){System.out.println("if B");}}}else{//使用B锁同步synchronized(MyLock.lockB){System.out.println("else A");//使用A锁同步synchronized(MyLock.lockA){System.out.println("else B");}}}}}


0 0
原创粉丝点击