一、线程基本知识

1、线程与进程

  进程:执行中的程序

  线程:轻量级的进程

    线程本身不能单独进行,必须放在一个进程中才能执行。

2、Java的线程模型

  1、新建状态

    线程被创建之后便处于新建状态。

  2、就绪状态

    新建状态的线程调用start方法、进入就绪状态。

    阻塞状态的线程解除阻塞之后进入就绪状态。

  3、运行状态

    处于就绪状态的线程获得cpu资源,该线程就进入了运行状态。

  4、阻塞状态

    是一个正在运行的线程因为一些原因让出cpu资源暂时中止而进入的状态。

  5、终止状态

    1、正常终止

    2、强制终止:stop、destory     System.exit(0)

    3、异常终止:当线程执行过程中产生了异常,线程会终止。

二、继承Thread类创建线程

public class MyThread extends Thread{

    public MyThread(String name) {
        super(name);
    }
    public void run() {
        for(int i=0;i<100;i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("MyThread"+i);
        }
    }
}
 

public class ThradDemo {

 

public static void main(String[] args) {

// TODO Auto-generated method stub

 

MyThread mt=new MyThread("线程1");

 

mt.start();

 

MyThread mt2=new MyThread("线程2");

 

mt2.start();

 

for(int i=0;i<100;i++) {

try {

Thread.sleep(100);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("主线程"+i);

}

System.out.println("程序执行完毕");

 

}

 

}

 

三、实现Runnable接口

1、实现Runnable接口

class A implements Runnable{
    public void run(){
    
    }    
}

A a=new A();
Thread t=new Thread(A);
Thread t1=new Thread(A,"线程1");
public class MyThread implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<10;i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("MyThread"+i);
        }
    }

    
}
public class RunnableDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MyThread m=new MyThread();
        
        Thread t=new Thread(m);
        
        t.start();
        
        for(int i=0;i<10;i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("主线程"+i);
        }
    }

}

 

2、两种方法比较

  extends Thread

  implements Runnable

  单继承,多实现。

四、多线程应用

1、多个线程并发执行

Java对于线程启动后唯一能保证的是每个线程都被启动且结束。

但是对于哪个先执行,哪个后执行,什么时候执行是没有保证的。

2、线程优先级

Java中优先级高的线程有更大的可能性获得CPU,但不是优先级高的总是先执行,也不是优先级低的线程总不执行。

最高的优先级10,最低的优先级1
可以用setPriority()、getPriority()设置、获取优先级
public class MyRunnable implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<100;i++) {
            System.out.println("*");
        }
    }

}
public class MyRunnable1 implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<100;i++) {
            System.out.println("+");
        }
    }

}
public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MyRunnable r=new MyRunnable();
        MyRunnable1 r1=new MyRunnable1();
        Thread t1=new Thread(r);
        Thread t2=new Thread(r1);
        
        System.out.println("t1的优先级"+t1.getPriority());
        System.out.println("t2的优先级"+t2.getPriority());
        
        t1.setPriority(Thread.MAX_PRIORITY);
        System.out.println("t1的优先级"+t1.getPriority());
        
        t2.setPriority(Thread.MIN_PRIORITY);
        System.out.println("t2的优先级"+t2.getPriority());
        
        t1.start();//就绪状态
        t2.start();//就绪状态
    }

}

五、线程调度的三个方法

1、休眠方法sleep()

sleep(毫秒)、sleep(毫秒、纳秒)
public class TestSleep {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        for(int i=0;i<10;i++) {
            System.out.println(i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

2、暂停方法yield()

a.yield()。a释放资源,大家抢资源。(a也会参与竞争)
public class TestYield {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Thread t1=new Thread(new MyRunnable1());
        Thread t2=new Thread(new MyRunnable2());
        
        t1.start();
        t2.start();
    }

}
class MyRunnable1 implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<200;i++) {
            System.out.println("+");
            Thread.yield();
        }
    }
    
}
class MyRunnable2 implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<200;i++) {
            System.out.println("*");
            Thread.yield();
        }
    }
    
}

3、挂起方法join()

a.join() 优先执行,相当于插队
public class TestJoin {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MyThread m=new MyThread();
        
        m.start();
        
        for(int i=0;i<10;i++) {
            if(i==5) {
                try {
                    m.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println("++++++++++");
        }
    }

}
class MyThread extends Thread{
    public void run() {
        for(int i=0;i<10;i++) {
            System.out.println("**********");
        }
    }
}

 六、同步问题Java解决方案

同步方法:当线程进入同步方法的时候,会获得同步方法所属对象的锁,一旦获得对象锁,则其他线程不能再执行被锁对象的其他任何同步方法。只有再同步方法执行完毕后释放了锁,其他线程才能执行。

  synchronized 方法声明{}

同步块:

  synchronized(资源对象){//需要进行同步的方法}

七、死锁问题

A线程需要申请资源1才能继续执行,而资源1被线程B所占用。而线程B需要申请资源2才能继续执行,而资源二被A线程所占有。

 

线程A占有资源2,需要申请资源1.

线程B占有资源1,需要申请资源2.

public class ResourceName {

    String resourceName;
    public ResourceName(String resourceName) {
        this.resourceName=resourceName;
    }
}
public class MyThread extends Thread{

    ResourceName r1;
    ResourceName r2;
    
    MyThread(ResourceName r1,ResourceName r2,String name){
        super(name);
        this.r1=r1;
        this.r2=r2;
    }
    public void run() {
        synchronized(r1) {
            System.out.println(this.getName()+"获得了"+r1.resourceName);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(this.getName()+"在等待"+r2.resourceName);
            synchronized(r2) {
                System.out.println(this.getName()+"获得了"+r2.resourceName);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}
public class Test1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ResourceName rs1=new ResourceName("资源1");
        ResourceName rs2=new ResourceName("资源2");
        ResourceName rs3=new ResourceName("资源3");
        
        MyThread t1=new MyThread(rs1,rs2,"线程1");
        MyThread t2=new MyThread(rs2,rs3,"线程2");
        MyThread t3=new MyThread(rs3,rs1,"线程3");
        
        t1.start();
        t2.start();
        t3.start();
    }

}