创建线程的方式有两种:
第一种:使用线程类Thread或者继承它的子类创建线程对象
第二种:定义接口类实现接口Runnable创建线程对象
多线程的好处:可以整合资源,提高系统资源的利用率
多线程中提供了同步方法、同步代码块以及加锁的方式实现多线程的同步
实现多线程:
classThread中有两个最重要的函数run()和start()。
1) run()函数必须进行覆写,把要在多个线程中并行处理的代码放到这个函数中。
2) 虽然run()函数实现了多个线程的并行处理,但我们不能直接调用run()函数,而是通过调用start()函数来调用run()函数。在调用start()的时候,start()函数会首先进行与多线程相关的初始化(这也是为什么不能直接调用run()函数的原因),然后再调用run()函数。
一、简单的多线程举例如下:
需求:设计一个模拟用户从银行取款的应用程序。设某银行账户存款额的初值为2000元,用线程模拟两个用户分别从银行取款的情况。两个用户分4次分别从银行的同一账户取款,每次取100元。
//方式一:继承Thread,并在同步方法中实现多线程同步
class Bank //定义银行类 { private static int Money=2000; public static synchronized void getmoney(int x) //同步方法 { Money = Money - x; try{Thread.sleep(10);} catch(InterruptedException e){}; System.out.println(Thread.currentThread().getName()+"剩余存款是:"+Money+" 元"); } } class Custom extends Thread //定义线程类继承Thread { public void run() { for(int i=0;i<4;i++) { Bank.getmoney(100); } } } class CustomBank { public static void main(String[] args) { Custom c1 = new Custom(); //创建两个线程c1、c2 Custom c2 = new Custom(); c1.start(); c2.start(); } }
//方式二:继承Thread,并在同步代码块中实现多线程同步
class Bank //定义银行类 { private static int Money=2000; public static void getmoney(int x) { synchronized(Bank.class) //同步代码块 { Money = Money - x; try{Thread.sleep(10);} catch(InterruptedException e){}; System.out.println(Thread.currentThread().getName()+"剩余存款是:"+Money+"元"); } } } class Custom extends Thread //定义线程类继承Thread { public void run() { for(int i=0;i<4;i++) { Bank.getmoney(100); } } } class CustomBank1 { public static void main(String[] args) { Custom c1 = new Custom(); //创建两个线程c1、c2 Custom c2 = new Custom(); c1.start(); c2.start(); } }
//方式三:实现Runnable接口,在同步方法或同步代码块中实现多线程同步
class Bank //定义银行类 { private int Money=2000; public synchronized void getmoney(int x) //同步方法 { { Money=Money-x; try{Thread.sleep(10);}catch(Exception e){}; System.out.println(Thread.currentThread().getName()+"剩余存款是:"+Money+" 元"); } } } class Custom implements Runnable //定义接口类实现接口Runnable { private Bank b = new Bank(); public void run() { for(int i=0;i<4;i++) { b.getmoney(100); } } } class CustomBank2 { public static void main(String[] args) { Custom c = new Custom(); Thread t1 = new Thread(c); Thread t2 = new Thread(c); t1.start(); t2.start(); } }
二、线程的技巧性写法:利用匿名内部类创建互不相关的多个线程
class Demo3 { public static void main(String[] args) { //第一个线程 new Thread() { public void run() { for(int i=0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"...."+i); } } }.start(); //第二个线程 for(int i=0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"...."+i); } //第三个线程 Runnable r = new Runnable() { public void run() { for(int i=0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"...."+i); } } }; new Thread(r).start(); } }
三、基本的线程的其他几种方法:
1、线程对象.setDaemon() 设置守护线程
2、线程对象.join() 等待该线程结束(顺序执行线程)
3、Thread.yield() 暂停当前正在执行的线程,执行其他的线程
4、线程对象.toStirng() 返回线程的名称、优先级、线程组
5、线程对象.setPriority() 设置线程的优先级
6、线程对象.getPriority() 获得线程的优先级
7、线程对象.interrupt() 中断当前线程
8、线程对象.isAlive() 判断线程是否正在运行
举例如下:
class DemoThread extends Thread { public void run() { for(int i=0;i<20;i++) { try { Thread.sleep(10); } catch (InterruptedException e) { System.out.println(e.toString()); } System.out.println(Thread.currentThread().getName()+"......"+i); //Thread.yield(); } } } class Demo2 { public static void main(String[] args) throws InterruptedException { DemoThread t1 = new DemoThread(); DemoThread t2 = new DemoThread(); //t1.setPriority(Thread.MIN_PRIORITY);//t1.setPriority(1); //t2.setPriority(Thread.MAX_PRIORITY);//t2.setPriority(10); //t1.setDaemon(true); //t2.setDaemon(true); t1.start(); //t1.join(); //t1.interrupt(); t2.start(); //t2.join(); //t2.interrupt(); System.out.println("t1线程是否正在运行:"+t1.isAlive()); System.out.println("t2线程是否正在运行:"+t2.isAlive()); System.out.println("t1线程的优先级是:"+t1.getPriority()); System.out.println("t2线程的优先级是:"+t2.getPriority()); System.out.println("t1线程的名称、优先级、线程组"+t1.toString()); System.out.println("t2线程的名称、优先级、线程组"+t2.toString()); for(int i=0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"......"+i); } System.out.println("over"); } }