一、多线程的随机性
1.多线程是异步的,代码顺序并非线程执行顺序,线程被调用的时机是随机的。
public class MyThread extends Thread {
@Override
public void run() {
super.run();
System.out.println("MyThread");
}
}
public class MultiProcess {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println(Thread.currentThread().getName());
}
}
运行结果:先打印了main函数的name,后执行start()方法
备注:
- Thread.java类中的start方法:
通知线程规划期此线程已经ready,go!坐等cpu调度,执行run方法执行。即异步执行。
- Thread.java类中的run方法:
run方法是同步执行,由main主线程来调度run方法,必须等run中的代码执行完毕,才可以执行后边代码
二、多线程的两种实现方式
1.继承Thread类
public class MyThread extends Thread {
private int i;
public MyThread(int i) {
super();
this.i = i;
}
@Override
public void run() {
super.run();
System.out.println(i);
}
}
public class MultiProcess {
public static void main(String[] args) {
MyThread t1 = new MyThread(1);
MyThread t2 = new MyThread(11);
MyThread t3 = new MyThread(111);
MyThread t4 = new MyThread(1111);
MyThread t5 = new MyThread(11111);
MyThread t6 = new MyThread(111111);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
System.out.println(Thread.currentThread().getName());
}
}
2.实现Runnable接口
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("运行中~");
}
}
public static void runnableTest(){
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);//可传thread或者runnable对象,交由别的线程调用
thread.start();
}
public static void main(String[] args) {
// threadTest();
runnableTest();
System.out.println(Thread.currentThread().getName());
}
备注:Thread构造函数 ,可传Runnable或者Thread对象,将该对象的run方法交给别的线程调用
3.实例变量与线程安全
3.1 线程间不共享变量
每个线程都有自己的count变量,不共享
public class ThreadA extends Thread{
private int count = 5;
public ThreadA(String name) {
super();
this.setName(name);
}
@Override
public void run() {
super.run();
while (count > 0){
count--;
System.out.println(this.currentThread().getName() + "计算,count = "+count);
}
}
}
public static void notShareVariable(){
ThreadA a = new ThreadA("A"); //每个线程有自己的count
ThreadA b = new ThreadA("B");
ThreadA c = new ThreadA("C");
a.start();
b.start();
c.start();
}
3.2 多个线程共享一个变量
多个线程共享一个变量,就会出现线程不安全问题
public static void shareVariable(){
ThreadA a = new ThreadA();
Thread thread1 = new Thread(a, "A");
Thread thread2 = new Thread(a, "B");
Thread thread3 = new Thread(a, "C");
thread1.start();
thread2.start();
thread3.start();
}
3.3 synchronized关键字
解决多线程共享变量时不安全问题,在线程的run方法前加synchronized关键字,加锁,使该部分代码变成互斥区或临界区,依次排队进行操作。
public class ThreadA extends Thread {
private int count = 5;
public ThreadA(String name) {
super();
this.setName(name);
}
public ThreadA() {
}
@Override
synchronized public void run() {
super.run();
count--;
System.out.println(this.currentThread().getName() + "计算,count = " + count);
}
}
//线程间共享变量
public static void shareVariable(){
ThreadA a = new ThreadA();
Thread thread1 = new Thread(a, "A");
Thread thread2 = new Thread(a, "B");
Thread thread3 = new Thread(a, "C");
Thread thread4 = new Thread(a, "D");
Thread thread5 = new Thread(a, "E");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}