注意:
1.直接继承线程类,线程之间操作的数据是独立的,即不会共用一个成员变量,除非用static静态修饰。
2.实现Runnable接口作为构造方法的实参,若传递的是同一个实参对象,即便成员变量不用static修饰,成员变量也会被线程共用。
3.非静态变量的数据共不共用, 主要看run()方法操作的对象是否是同一个对象。
1.创建一个类,然后继承Thread类,然后再重写run()方法。通过创建此类的对象调用start方法
package 练习五;
public class t extends Thread{
private int num;
@Override
public synchronized void run() {
while (num < 10) {
System.out.println(num);
num++;
}
}
public static void main(String[] args) {
t t1 = new t();
t1.start();
t t2 = new t();
t2.start();
}
}
2.通过实现Runnable接口作为线程类的构造函数的实参。
package 练习六;
public class t implements Runnable{
private int num=0;
@Override
public void run() {
while (num < 10) {
System.out.println(num);
num++;
}
}
public static void main(String[] args) {
t t1 = new t();
t t2 = new t();
Thread thread = new Thread(t1);
thread.start();
//两个构造方法的参数是同一个对象,说明执行的是同一个对象的数据。即一个num变量被两个线程共用。
Thread thread1 = new Thread(t1);
thread1.start();
}
}
3.非静态变量的数据共不共用, 主要看run()方法操作的对象是否是同一个对象。
public class demo extends Thread{
private middle m;
public demo(middle mid){
this.m=mid;
}
@Override
public synchronized void run() {
m.method();
}
public static void main(String[] args) {
//操作的是同一个数据。
// demo.middle m = new middle();
// demo d1 = new demo(m);
// d1.start();
// demo d2 = new demo(m);
// d2.start();
//操作的是不同数据
demo.middle m = new middle();
demo.middle m1 = new middle();
demo d1 = new demo(m);
d1.start();
demo d2 = new demo(m1);
d2.start();
}
//内部类
public static class middle {
private int num;
public synchronized void method() {
while (num < 10) {
System.out.println(num);
num++;
}
}
}
}
4.继承Thread对象中的run:测试一下run方法加synchronized是否有用。
public class thread extends Thread{
public int i;
@Override
public synchronized void run() {
while (true) {
System.out.println(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
public static void main(String[] args) {
thread t1 = new thread();
thread t2 = new thread();
t1.start();
t2.start();
}
}
####运行结果为:各执行各的,毫不相关,两个线程都在进行。(估计是t1和t2是不同对象,所以没用)
5.实现Runnable接口中的run:测试一下run方法加synchronized是否有用。
public class thread implements Runnable{
public int i;
@Override
public synchronized void run() {
while (true) {
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
public static void main(String[] args) {
//会被锁住
thread t = new thread();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
t2.start();
/*
//不会被锁住
thread t = new thread();
thread tt = new thread();
Thread t1 = new Thread(t);
Thread t2 = new Thread(tt);
t1.start();
t2.start();
*/
}
}
注意:说明run方法是由Runnable实现类的对象或继承类对象调用的。锁不锁定看对象是否一样。如t.run();
//可看做new Thread(t)是为对象t创建一个线程t1,实质是t1执行的是t.run()
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
t2.start();
//相当于下面对象t调用的两个方法同时在执行。
t.run();
t.run();
可看做new Thread(t)是为对象t创建一个线程t1,实质是t1执行的是t.run():这理解应该是错误的
重点:
调用start() 会触发多线程执行 ;
调用run() 还是当做执行了一个普通方法,没有多线程执行。