Java-第二课线程
废话:“老板,手机是水货好,还是行货好喔?”,“当然水货好涩!你看街上哪有水货手机的维修中心嘛!”--糗百
走着:Java中线程有两种实现方式:1、extends Thread 类 2、implements Runable 接口
1、对于Thread类
1 public class ThreadDemo01 extends Thread { 2 public void run() { 3 for (int i = 0; i < 10; i++) { 4 System.out.print(Thread.currentThread().getName()+":"+i+","); 5 } 6 } 7 public static void main(String[] args) { 8 ThreadDemo01 t1=new ThreadDemo01(); 9 ThreadDemo01 t2=new ThreadDemo01(); 10 t1.setName("a");//给线程设置名称 11 t2.setName("b"); 12 t1.setPriority(MAX_PRIORITY);//设置优先级 13 t2.setPriority(NORM_PRIORITY); 14 t1.start();//调用线程 15 t2.start(); 16 } 17 }
结果:a:0,b:0,a:1,b:1,a:2,b:2,a:3,b:3,a:4,b:4,a:5,b:5,a:6,a:7,a:8,a:9,b:6,b:7,b:8,b:9,
把希望并行处理的代码都放在run() 中,stat() 用于自动调用run()。实例化一次是一个线程。线程的优先级的范围是(1-10),Java线程的优先级高只是说明该线程先执行的概率大,不代表一点会先执行。
2、对于Runable接口
1 public class ThreadDemo02 implements Runnable { 2 public void run() { 3 for (int i = 0; i < 10; i++) { 4 System.out.print(Thread.currentThread().getName()+":"+i+","); 5 } 6 } 7 public static void main(String[] args) { 8 Runnable r1 = new ThreadDemo02(); 9 Thread t1 = new Thread(r1);//创建线程对象 10 Thread t2 = new Thread(r1); 11 t1.setName("a");//给线程设置名称 12 t2.setName("b"); 13 t1.start();//启动线程 14 t2.start(); 15 } 16 }
结果:a:0,b:0,a:1,b:1,a:2,b:2,a:3,b:3,a:4,b:4,a:5,b:5,a:6,b:6,a:7,b:7,a:8,b:8,a:9,b:9,
实现Runable接口只需要实例化一次,然后可以创建多个线程,更灵活,推荐使用Runable接口。
3、线程的同步synchronized
public class ThreadDemo02 implements Runnable { /*第一种synchronized*/ // public void run() { // synchronized(this){ // for (int i = 0; i < 10; i++) { // System.out.print(Thread.currentThread().getName()+":"+i+","); // } // } // } /*第二种synchronized*/ public synchronized void run() { for (int i = 0; i < 10; i++) { System.out.print(Thread.currentThread().getName()+":"+i+","); } } public static void main(String[] args) { Runnable r1 = new ThreadDemo02();//向下转型 Thread t1 = new Thread(r1,"a"); Thread t2 = new Thread(r1,"b"); t1.start(); t2.start(); } }
两种同步的结果都是:a:0,a:1,a:2,a:3,a:4,a:5,a:6,a:7,a:8,a:9,b:0,b:1,b:2,b:3,b:4,b:5,b:6,b:7,b:8,b:9,
synchronized是同步锁,加上之后,只有在线程运行结束之后才会放锁。synchronized作用于同一个对象的不同进程,不能作用于多个对象。
public class ThreadDemo02 implements Runnable { public synchronized void run() { for (int i = 0; i < 10; i++) { System.out.print(Thread.currentThread().getName()+":"+i+","); } } public static void main(String[] args) { Runnable r1 = new ThreadDemo02(); Runnable r2 = new ThreadDemo02();//实例化两个对象的时候 Thread t1 = new Thread(r1,"a"); Thread t2 = new Thread(r2,"b");//两个对象的不同的线程 t1.start(); t2.start(); } }
结果:a:0,b:0,a:1,b:1,a:2,b:2,a:3,b:3,a:4,b:4,b:5,b:6,a:5,a:6,a:7,a:8,a:9,b:7,b:8,b:9,
假如是两个不同的对象的不同线程是不能加synchronized同步锁的。没有意义。
public class ThreadDemo03 implements Runnable { public void run() { /*不同步的循环*/ for (int k = 0; k < 3; k++) { System.out.print(Thread.currentThread().getName()+ ",no:" + k+";"); } /*同步的循环*/ synchronized (this) { for (int k = 0; k < 3; k++) { System.out.print(Thread.currentThread().getName()+ ",yes:" + k+";"); } } } public static void main(String[] args) { Runnable r = new ThreadDemo03(); Thread t1 = new Thread(r, "a"); Thread t2 = new Thread(r, "b"); t1.start(); t2.start(); } }
结果:a,no:0;b,no:0;b,no:1;b,no:2;a,no:1;b,yes:0;a,no:2;b,yes:1;b,yes:2;a,yes:0;a,yes:1;a,yes:2;
这个能够更只管的看到,当b线程先加上synchronized时只能它完成释放掉,另一个线程才能调用
4、sleep()
public class ThreadDemo04 implements Runnable { public void run() { for (int k = 0; k < 5; k++) { if(k==2){ try { Thread.currentThread(); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.print(Thread.currentThread().getName()+":"+k); } } public static void main(String[] args) { Runnable r = new ThreadDemo04(); Thread t1 = new Thread(r, "a"); Thread t2=new Thread(r,"b"); // t1.setPriority(Thread.MAX_PRIORITY); // t2.setPriority(Thread.MIN_PRIORITY); t1.start(); t2.start(); } }
没有优先级结果:a:0a:1b:0b:1b:2b:3b:4a:2a:3a:4
有优先级的结果:a:0a:1b:0b:1b:2a:2a:3a:4b:3b:4
一个线程在sleep的时候,并不会释放这个对象的锁标志。但是当设置了优先级的时候,一个线程在sleep()中时,另一个线程可以执行。
5、jion()
public class ThreadDemo06 implements Runnable { public static int a = 0; public void run() { for (int k = 0; k < 5; k++) { a = a + 1; } } public static void main(String[] args) { Runnable r = new ThreadDemo06(); Thread t = new Thread(r); t.start(); // try { // t.join();//不加的话,很难是5。加上之后a就是5 ? // } catch (InterruptedException e) { // e.printStackTrace(); // } System.out.println(a); } }
不加jion结果:0
加jion的结果:5
第一个为什么是0呢?因为为线程分配资源需要时间,而main方法执行完t.start()方法后继续往下执行System.out.println(a)。这个时候得到的结果是a还没有被改变的值0。jion()方法能够让一个线程在方法之前完成,jion()会抛出异常所以需要try,catch,所以加上之后输出的是5。
6、yield()
public class ThreadDemo08 implements Runnable { public void run() { for (int k = 0; k < 10; k++) { if (k == 5 && Thread.currentThread().getName().equals("t1")){ Thread.yield(); } System.out.print(Thread.currentThread().getName() + ":" + k+";"); } } public static void main(String[] args) { Runnable r = new ThreadDemo08(); Thread t1 = new Thread(r, "a"); Thread t2 = new Thread(r, "b"); // t1.setPriority(Thread.MAX_PRIORITY); // t2.setPriority(Thread.MIN_PRIORITY); t1.start(); t2.start(); } }
没有设置优先级的:a:0;a:1;b:0;a:2;b:1;a:3;b:2;a:4;b:3;a:5;b:4;a:6;b:5;a:7;b:6;a:8;b:7;a:9;b:8;b:9;
设置优先级的:b:0;a:0;b:1;a:1;b:2;a:2;b:3;a:3;b:4;a:4;b:5;a:5;b:6;a:6;b:7;a:7;b:8;a:8;b:9;a:9;
api上说的是:暂停当前正在执行的线程对象,并执行其他线程。yield() 方法与sleep() 方法相似,只是它不能由用户指定线程暂停多长时间。按照SUN的说法:sleep方法可以使低优先级的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会。而yield()方法只能使同优先级的线程有执行的机会,就是加不加优先级无所谓。不知道有什么作用。
7、wait(), notify()
public class ThreadDemo09 implements Runnable { public static int k = 0; public synchronized void run() { if (k == 0) { for (int i = 0; i < 10; i++) { k++; if (k == 5) { try { this.wait();//休息 } catch (Exception e) {} } } } if (k != 0) { System.out.println(Thread.currentThread().getName()+"线程的k=" + k); this.notify();//唤醒 } } public static void main(String[] args) { Runnable r = new ThreadDemo09(); Thread t1 = new Thread(r, "a"); Thread t2 = new Thread(r, "b"); t1.start(); t2.start(); } }
结果:b线程的k=5
a线程的k=10
wait()休息, notify()唤醒。需要在synchronized中使用,调用wait()方法的时候会释放锁标志。唤醒的时候会唤醒休息中的线程。
a线程先执行,因为是synchronized同步锁,所以a线程执行完之前是不是释放锁的。当k=5的时候,a调用了wait()方法自动释放锁,这个时候b线程执行,因为k是静态变量,所以这个时候b线程的k=5直接输出,然后调用了notify()方法,唤醒wait()中的线程,a线程继续执行,当k=10的时候,输出。
结束:实际上,程序中的多个线程并不是同时执行的。除非线程正在真正的多CPU计算机系统上执行,否则线程使用单CPU必须轮流执行。但是,由于这发生的很快,我们常常认为这些线程是同时执行的。线程的每一次执行结果都不相同。
浙公网安备 33010602011771号