线程运行时的特点
1.线程运行时的随机性
线程的运行是具有随机性的 比如以下代码
public class Demo03 {
public static void main(String[] args) {
Thread t=new Demo03Thread();
t.start();
try {
for (int i = 0; i < 5; i++) {
System.out.println("main:运行main方法");
Thread.sleep(100);//当前线程睡眠
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
class Demo03Thread extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println("Thread: 运行线程的方法");
Thread.sleep(100);//让当前线程睡眠100毫秒
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
多运行基础会发现:
每一次运行的结果都有可能不一样,这就是线程随机性导致的,在多线程编程中,代码的执行结果与代码的执行顺序或调用顺序是无关的。线程是一个子任务,如果当前的线程存在堵塞状况,cpu很可能先去运行其他线程然后再来运行这个线程。这和cpu的调度算法有关系。
2.start()方法的执行顺序与线程的启动顺序不一致
public class Demo04 {
public static void main(String[] args) {
Thread t1 = new Demo04Thread(1);
Thread t2 = new Demo04Thread(2);
Thread t3 = new Demo04Thread(3);
Thread t4 = new Demo04Thread(4);
Thread t5 = new Demo04Thread(5);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
class Demo04Thread extends Thread{
private int val;
public Demo04Thread(int val){
this.val = val;
}
@Override
public void run() {
System.out.println("val=" + val);
}
}
运行结果 会返现:
start()方法的执行顺序与线程的启动顺序不一致 。也就是说由于每个线程的执行情况不同,可能会有堵塞当前线程 执行下一个线程的情况发生。
3.线程安全与成员变量
线程类中的成员变量分为共享与不共享两种 ,由于共享与不共享的特性, 这就产生了线程安全这一问题。
3.1 不共享数据
public class Demo05 {
public static void main(String[] args) {
Thread t1 = new Demo06Thread();
Thread t2 = new Demo06Thread();
Thread t3 = new Demo06Thread();
t1.start();
t2.start();
t3.start();
}
}
class Demo06Thread extends Thread {
private int count = 5;
@Override
public void run() {
while (count > 0) {
count--;
System.out.println(Thread.currentThread().getName() + ": count=" + count);//Thread.currentThread().getName() 是获取当前线程的名称
}
}
}
运行结果为:
可以看出每个线程的数据都是独立的 ,线程与线程之间并没有共享数据
3.2 共享数据
public class Demo06 {
public static void main(String[] args) {
Thread t = new Demo06Thread();// 将线程类Demo06Thread()作为参数传递给其他线程
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
Thread t5 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
class Demo06Thread extends Thread {
private int count = 5;
@Override
public void run() {
count--;
System.out.println(Thread.currentThread().getName() + ", count=" + count);
}
}
运行结果为:
共享数据 很可能无法保持数据的一直性 造成数据的脏读幻读,这就产生了线程安全问题