rss· 投稿· 设为首页· 加入收藏· 繁體版
当前位置: 火魔网 » 程序开发 » Java基础

关于java线程的实例

/*
 线程的状态:
  新建
  可运行
  运行
  阻塞
  终止
 
 实现线程的两种方法:1、继承thread类。2、实现Runnable接口。
  Runnable:如果不用修改线程(除了run()方法外)其他方法,则用实现Runnable接口的方法。
           多个线程共享同一个变量,操纵同一对象。
        实现java.lang.Runnable接口,必须实现run()方法。
        当创建并运行线程时,实现类的实例作为参数传递给Thread类的构造函数,然后调用Thread类的start()方法执行线程
  Thread:在多线程时,独立享有变量。
         创建java.lang.thread类的子类,并覆盖Thread类的run()方法。
         子类通过调用start()方法执行线程
 
 线程的调度(由时间片轮转来实现线程之间的转换)
  1、一个线程对象的start方法只能被执行一次
  2、一个时刻只是一个线程在运行
  3、休眠,使线程停止执行一段时间,该时间由自定的毫秒数决定。
   sleep方法是静态方法,它只是暂停当前执行中的线程,因此不能使用sleep方法来暂停其他线程的执行。
  4、线程是抢占式的:优先级
  5、运行到不再是可运行的,或另一个更高优先级的线程成为可运行
  6、所有可运行线程按优先级保存在缓冲池中
  7、优先权(priority),MAX_PRIORITY=10、NORM_PRIORITY=5、MIN_PRIORITY=1
  8、加入到某个线程(join),一个线程可以在其它线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行。
    如果某个线程thread在另一个线程上调用thread.join(),此线程将被挂起,直到目标线程thread结束才恢复。

 线程的同步:锁定任何对象所占用的内存,试的同一时刻只能有一个线程在使用它。通过synchronized关键字来实现的。

 线程的同步有两种方式:
  1、同步块(同步代码段):用加锁和解锁来控制当前线程数,并需要传入对象(如果传入的是this,则能和同步方法同步)。
    synchronized(syncObject){//在对象syncObject上加锁,同一时刻只能有一个线程访问}
  2、同步方法:用加锁和解锁来控制当前线程数,并用this监视器监视。
        在当前对象上加锁,同一时刻只能有一个线程访问当前对象的此方法(保证该方法中的所有指令同步进行,中间不会被打断)
        在对象锁释放之前,该对象上其他同步方法也不能被访问
  当我们同步的是静态方法是,所用的该类所对应的class方法。
  同步的死锁: 例.当线程1,进入同步块A时,线程2,进入同步块B,而此时线程1要在同步块A中访问同步块B,线程2要在同步块B中访问同步块A,因线程1,进入同步块A时,同步块A加锁(同步块B同此),所以线程1需要等待同步块B解锁(线程2亦然),彼此都不能完成,形成死锁。
  其中resume()和suspend()方法,容易造成线程的死锁,不建议使用。
 
 wait、notify、notifyall 必须在同步方法或块中被调用eg.
 每一个对象除了有一个锁之外,还有一个等待队列(wait set),当一个对象刚创建的时候,大的等待队列是空的。
 在当前线程锁住对象的锁后,去调用该对象的wait方法。
 当调用对象的notify方法时,将从该对象的等待队列中删除一个任意选择的线程,这个线程将再次成为可运行的线程。
 当调用对象的notifyAll方法时,将从该对象的等待队列中删除所有等待的线程,这些线程将成为可运行的线程。
 wait和notify主要用于producer-consumer这种关系中。
 注:应该作用于同一个对象!!!
 
 线程的终止
  1、设置一个flag变量
  2、结合interrupt()方法
  
 注: 1、线程是通过start()方法来调用的,调用线程类中的run()方法,是不能启动线程的,那只是调用了run()方法而已。
   2、一个线程重复调用是非法的。
   3、优先权高,不代表就先运行,只是抢占cpu时间的几率更高。

*/

//实例一----Thread和Runnable
/*
 实现线程的两种方法:1、继承thread类。2、实现Runnable接口。
  Runnable:实现java.lang.Runnable接口,必须实现run()方法。
        当创建并运行线程时,实现类的实例作为参数传递给Thread类的构造函数,然后调用Thread类的start()方法执行线程
  Thread:创建java.lang.thread类的子类,并覆盖Thread类的run()方法。
         子类通过调用start()方法执行线程
*/
//Thread例
public class PrimeThread extends Thread {

    public PrimeThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        for(int i=0;i<20;i++)
        {
            System.out.println(getName()+" NO."+i);
        }
    }
}
public class ThreadTest {
    public static void main(String[] args) {
        Thread thread1=new PrimeThread("geass");
        Thread thread2=new PrimeThread("holic");
        Thread thread3=new PrimeThread("clannad");
        Thread thread4=new PrimeThread("code");
        thread4.setName("liar"); //将线程的名字改为liar
        //启动线程
        thread1.start();
        System.out.println("--------------------Thread1:geass started");
        thread2.start();
        System.out.println("--------------------Thread2:holic started");
        thread3.start();
        System.out.println("--------------------Thread3:clannad started");
        thread4.start();
        System.out.println("--------------------Thread4:liar started");
    }
}
//Runnable例
public class PrimeRunnable implements Runnable{
    private String name;

    public PrimeRunnable(String name) {
        this.name = name;
    }

    public void run() {
        for(int i=0;i<20;i++)
        {
            System.out.println(name+" NO."+i);
        }
    }
}
public class RunnableTest {
    public static void main(String[] args) {
        Runnable run1=new PrimeRunnable("adieu");
        Runnable run2=new PrimeRunnable("antique");
        Runnable run3=new PrimeRunnable("highness");
        Runnable run4=new PrimeRunnable("lord");
        new Thread(run1).start();
        System.out.println("--------------------Thread:adieu started");
        new Thread(run2).start();
        System.out.println("--------------------Thread:antique started");
        new Thread(run3).start();
        System.out.println("--------------------Thread:highness started");
        new Thread(run4).start();
        System.out.println("--------------------Thread:lord started");
    }
}

//实例二----Thread和Runnable的区别
/*
*/
//
public class DifThread extends Thread{
    private int i;

    public DifThread(String name) {
        setName(name);
    }

    public int getI() {
        return i;
    }

    @Override
    public void run() {
        for(int j=0;j<5;j++){
            i+=j;
            System.out.println(getName()+" NO."+i);
        }
    }
}
public class DifThreadTest {
    public static void main(String[] args) {
        Thread t1=new DifThread("geass");
        t1.start();
        t1.start(); //会抛出异常,要采用新的实例!!!
        //Thread t2=new DifThread("holic");
        //t2.start();
    }
}
//
public class DifRunnable implements Runnable{
    private String name;
    private int i;

    public DifRunnable(String name) {
        this.name = name;
    }

    public void run() {
        for(int j=0;j<5;j++)
        {
            i+=j;
            System.out.println(name+" NO."+i);
        }
    }
}
public class DifRunnableTest {
    public static void main(String[] args) {
        Runnable r1=new DifRunnable("adieu");
        //直接调用
        new Thread(r1).start();
        new Thread(r1).start();
    }
}

//实例三----进程的优先级
/*
 线程是抢占式的:优先级
 运行到不再是可运行的,或另一个更高优先级的线程成为可运行
 所有可运行线程按优先级保存在缓冲池中
 优先权(priority),MAX_PRIORITY=10、NORM_PRIORITY=5、MIN_PRIORITY=1
*/
//例1
class MaxThread extends Thread{

    public MaxThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        //setPriority(Thread.MAX_PRIORITY);
        for(int i=0;i<10;i++){
            System.out.println(getName()+"是高优先级"+10);
        }
    }   
}
class NorThread extends Thread{

    public NorThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        //setPriority(Thread.NORM_PRIORITY);
        for(int i=0;i<10;i++){
            System.out.println(getName()+"是中优先级"+5);
        }
    } 
}
public class PriorityTest {
    public static void main(String[] args) {
        Thread t1=new NorThread("geass");
        Thread t2=new MaxThread("holic");

        t1.setPriority(Thread.NORM_PRIORITY);
        t2.setPriority(Thread.MAX_PRIORITY);

        t1.start();
        t2.start();
    }
}

//例2
class PrioThread extends Thread{

    public PrioThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        System.out.println("当前进程名为:"+currentThread().getName()+",优先级为:"+currentThread().getPriority());
    }

}
public class TestPriority {
    public static void main(String[] args) {
        System.out.println("线程名\t优先级");
        Thread current=Thread.currentThread();
        System.out.println(current.getName()+"\t");
        System.out.println(current.getPriority()+"\t");

        Thread t1=new PrioThread("geass");
        Thread t2=new PrioThread("holic");
        Thread t3=new PrioThread("adieu");

        t2.setPriority(Thread.MAX_PRIORITY);
        t1.setPriority(Thread.MIN_PRIORITY);
        t3.setPriority(Thread.NORM_PRIORITY);

        t1.start();
        t2.start();
        t3.start();
    }
}

//实例四----进程的join
/*
 加入到某个线程(join),一个线程可以在其它线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行。
 如果某个线程thread在另一个线程上调用thread.join(),此线程将被挂起,直到目标线程thread结束才恢复。
*/
//
public class JoinTest {
    public static void main(String[] args) {
        MyRunner r=new MyRunner();
        MyRunner1 r1=new MyRunner1();
        Thread t=new Thread(r);
        Thread t1=new Thread(r1);
        t.start();  
        try{
            t.join(); //当t新城结束,t1线程才能恢复
        }catch(Exception ex){
            ex.printStackTrace();
        }
        t1.start();
        try{
            t1.join();
        }catch(Exception ex){
            ex.printStackTrace();
        }
        for(int i=0;i<200;i++){
            System.out.println("Main Thread: "+i);
        }
    }
}
class MyRunner implements Runnable{
    public void run(){
        for(int i=0;i<200;i++){
            System.out.println("Sub Thread: "+i);
        }
    }
}
class MyRunner1 implements Runnable{
    public void run(){
        for(int i=0;i<200;i++){
            System.out.println("Thread: "+i);
        }
    }
}

//实例五----进程的sleep
/*
 休眠,使线程停止执行一段时间,该时间由自定的毫秒数决定。
 sleep方法是静态方法,它只是暂停当前执行中的线程,因此不能使用sleep方法来暂停其他线程的执行。
*/
//
public class SleepTest {
    public static void main(String[] args) {
    SleepThread st1=new SleepThread("geass");
    SThread st2=new SThread("holic");
   
    st1.start();
    st2.start();
    }

class SleepThread extends Thread{

    public SleepThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        try{
            Thread.sleep(1000);
        }catch(Exception ex){
            ex.printStackTrace();
        }
        for(int i=0;i<200;i++){
            System.out.println("线程名为:"+currentThread().getName()+", 线程号为:"+i);
        }
    }
}

class SThread extends Thread{
    public SThread(String name) {
        super(name);
    }
    @Override
    public void run() {
        for(int i=0;i<200;i++){
            System.out.println("线程名为:"+currentThread().getName()+", 线程号为:"+i);
        }
    }
}

//实例六----进程的synchronized
/*
 休眠,使线程停止执行一段时间,该时间由自定的毫秒数决定。
 sleep方法是静态方法,它只是暂停当前执行中的线程,因此不能使用sleep方法来暂停其他线程的执行。
*/
//
public class BankAccount {

    private int balance = 100;

    public int getbalance() {
        return balance;
    }

    public void withdraw(int amount){
        balance-=amount;
    }
}

//
public class WifeHusband implements Runnable {

    private BankAccount account = new BankAccount();

    public void run() {
        while (account.getbalance() > 0) {
            makeWithdraw(10);
            if (account.getbalance() < 0) {
                System.out.println("透支");
            }
        }
    }
  //方式一、同步方法
   /* synchronized private void makeWithdraw(int amount) {
        if (account.getbalance() >= amount) {
            System.out.println(Thread.currentThread().getName() + " is about to eithdraw");
            try {
                System.out.println(Thread.currentThread().getName() + " is going to sleep");
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " wake up");
            account.withdraw(amount);
            System.out.println(Thread.currentThread().getName() + " completes the withdraw");
        } else {
            System.out.println("Sorry,not enough for" + Thread.currentThread().getName());
        }
    }*/
    //方式二、同步块
    private void makeWithdraw(int amount) {
        synchronized (this) {
            if (account.getbalance() >= amount) {
                System.out.println(Thread.currentThread().getName() + " is about to eithdraw");
                try {
                    System.out.println(Thread.currentThread().getName() + " is going to sleep");
                    Thread.sleep(500);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " wake up");
                account.withdraw(amount);
               
            } else {
                System.out.println("Sorry,not enough for " + Thread.currentThread().getName());
            }
        }
        System.out.println(Thread.currentThread().getName() + " completes the withdraw");
    }

    public static void main(String[] args){
        WifeHusband wh=new WifeHusband();
        Thread wife = new Thread(wh);
        Thread husband=new Thread(wh);
        wife.setName("Jeffer");
        husband.setName("Smith");
        wife.start();
        husband.start();
    }
}

顶一下
(0)
踩一下
(0)