并发编程: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!

 

 
原文地址:https://www.cnblogs.com/zhangjianbing/p/9083102.html