并发编程:Thread和Runable-01
1.继承Thread类(不推荐)
代码很简单,就不说了
public class ThreadTest02 { public static void main(String[] args) { new UserThread("A").start(); System.out.println("结束。。。"); } public static class UserThread extends Thread { UserThread(String name) { this.setName(name); } public void run() { System.out.println(Thread.currentThread().getName() + " run方法执行了。。。"); } } }
2.实现Runable接口
public class RunableTest01 { public static void main(String[] args) { Thread thread = new Thread(new UserThread(), "A"); thread.start(); System.out.println("结束。。。"); } public static class UserThread implements Runnable { public void run() { System.out.println(Thread.currentThread().getName() + " run方法执行了"); } } }
以上运行的结果:
结束。。。
A run方法执行了
run和start的区别?
- start()它的作用是启动一个新线程。通过start()方法来启动的新线程,处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行相应线程的run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。start()不能被重复调用。用start方法来启动线程,真正实现了多线程运行,即无需等待某个线程的run方法体代码执行完毕就直接继续执行下面的代码。这里无需等待run方法执行完毕,即可继续执行下面的代码,即进行了线程切换。
- run()就和普通的成员方法一样,可以被重复调用。如果直接调用run方法,并不会启动新线程!程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到多线程的目的。总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
数据共享与非共享
1.数据不共享
新起三个不同的线程,对成员变量操作,互不影响
public class ThreadShareTest01 { public static void main(String[] args) { Thread thread1 = new Thread(new UserThread(), "A"); Thread thread2 = new Thread(new UserThread(), "B"); Thread thread3 = new Thread(new UserThread(), "C"); thread1.start(); thread2.start(); thread3.start(); } public static class UserThread extends Thread { private int count = 10; public void run() { while (count > 0) { count--; System.out.println(Thread.currentThread().getName() + " 线程过来了,count变为:" + count); } System.out.println("count小于0了"); } } }
结果:
A 线程过来了,count变为:9 A 线程过来了,count变为:8 A 线程过来了,count变为:7 A 线程过来了,count变为:6 A 线程过来了,count变为:5 A 线程过来了,count变为:4 A 线程过来了,count变为:3 A 线程过来了,count变为:2 A 线程过来了,count变为:1 A 线程过来了,count变为:0 count小于0了 B 线程过来了,count变为:9 B 线程过来了,count变为:8 B 线程过来了,count变为:7 B 线程过来了,count变为:6 B 线程过来了,count变为:5 B 线程过来了,count变为:4 B 线程过来了,count变为:3 B 线程过来了,count变为:2 B 线程过来了,count变为:1 B 线程过来了,count变为:0 count小于0了 C 线程过来了,count变为:9 C 线程过来了,count变为:8 C 线程过来了,count变为:7 C 线程过来了,count变为:6 C 线程过来了,count变为:5 C 线程过来了,count变为:4 C 线程过来了,count变为:3 C 线程过来了,count变为:2 C 线程过来了,count变为:1 C 线程过来了,count变为:0 count小于0了
2.数据共享
public class ThreadShareTest02 { public static void main(String[] args) { UserThread userThread = new UserThread(); Thread thread1 = new Thread(userThread, "A"); Thread thread2 = new Thread(userThread, "B"); Thread thread3 = new Thread(userThread, "C"); Thread thread4 = new Thread(userThread, "D"); Thread thread5 = new Thread(userThread, "E"); Thread thread6 = new Thread(userThread, "F"); Thread thread7 = new Thread(userThread, "G"); Thread thread8 = new Thread(userThread, "H"); Thread thread9 = new Thread(userThread, "I"); Thread thread10 = new Thread(userThread, "J"); thread1.start(); thread2.start(); thread3.start(); thread4.start(); thread5.start(); thread6.start(); thread7.start(); thread8.start(); thread9.start(); thread10.start(); } public static class UserThread extends Thread { private int count = 10; public void run() { count--; System.out.println(Thread.currentThread().getName() + " 线程过来了,count变为:" + count); } } }
结果:
有问题了!
A 线程过来了,count变为:8
B 线程过来了,count变为:8
C 线程过来了,count变为:7
E 线程过来了,count变为:5
D 线程过来了,count变为:5
J 线程过来了,count变为:3
G 线程过来了,count变为:3
F 线程过来了,count变为:2
I 线程过来了,count变为:1
H 线程过来了,count变为:0
解决办法?
最简单的是在run方法加上synchronized,其实还有别的更高效的方法,后面会说到
public synchronized void run() { count--; System.out.println(Thread.currentThread().getName() + " 线程过来了,count变为:" + count); }
改善结果:
A 线程过来了,count变为:9
B 线程过来了,count变为:8
D 线程过来了,count变为:7
E 线程过来了,count变为:6
C 线程过来了,count变为:5
G 线程过来了,count变为:4
H 线程过来了,count变为:3
I 线程过来了,count变为:2
J 线程过来了,count变为:1
F 线程过来了,count变为:0
ok!