要实现多线程的开发,就像必须存在主类那样,也需要一个线程主体类,这个类必须继承Thread类或实现Runable接口。此外还需在该类中覆写run()方法。
1、多线程的实现方式以下代码是通过继承Thread类实现多线程的开发。线程主体要写在run()方法里,通过在main()方法里实例化线程类,获取线程对象。再通过线程对象的start()方法启动线程,此时3个线程将会并发执行。
public class MyThread extends Thread {
private String name;
public MyThread(String name){
this.name = name;
}
@Override
public void run() {
for(int i=1;i<=5;i++){
System.out.println(this.name+":i="+i);
}
}
public static void main(String[] args) {
MyThread a = new MyThread("线程A");
MyThread b = new MyThread("线程B");
MyThread c = new MyThread("线程C");
a.start();
b.start();
c.start();
}
}
执行结果是3个线程并发执行(如下图)。当不使用start()方法启动线程而是调用run()方法时,程序将会像调用普通方法一样顺序执行。
利用Runnable接口实现卖票的程序例子。
public class Ticket implements Runnable {
private int ticket = 5;
@Override
public void run() {
for(int i=0;i<10;i++){
if(this.ticket > 0){
System.out.println(Thread.currentThread().getName()+"处还有余票:"+(this.ticket--)+"张,i="+i);
}
}
}
public static void main(String[] args) {
Ticket t = new Ticket();
new Thread(t,"张三").start();
new Thread(t,"李四").start();
new Thread(t,"王五").start();
}
}
使用Runnable接口实现多线程,最后还是要用Thread的start()方法启动线程。
线程也有优先级,通过setPriority()方法设置,该方法接收一个int型参数。
public class Priority implements Runnable {
@Override
public void run() {
for(int i=1;i<=5;i++){
System.out.println(Thread.currentThread().getName()+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Priority p = new Priority();
Thread p1 = new Thread(p,"线程A");
Thread p2 = new Thread(p,"线程B");
p1.setPriority(Thread.MAX_PRIORITY);
p2.setPriority(Thread.MIN_PRIORITY);
p1.start();
p2.start();
new Thread(p,"线程C").start();
}
}
执行结果是,A的优先级最高,最先执行;B的优先级最低,最后执行。但是真实的执行顺序大致如此,并不绝对。sleep()方法用于让线程休眠,参数的单位是毫秒。
public class Ticket implements Runnable {
private int ticket = 5;
@Override
public void run() {
for(int i=0;i<20;i++){
synchronized(this){
if(this.ticket > 0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"处还有余票:"+(this.ticket--)+"张,i="+i);
}
}
}
}
public static void main(String[] args) {
Ticket t = new Ticket();
new Thread(t,"张三").start();
new Thread(t,"李四").start();
new Thread(t,"王五").start();
}
}
上例使用synchronized代码块进行线程同步(也可在方法前加该关键字构成同步方法),使用同步的好处在于避免产生负票数,保证数据的安全。简单的说同步就是一个线程要等待另一个线程执行完毕,在多个线程访问同一资源时,要考虑同步问题。但过多的同步可能造成死锁。