关于线程
1、什么是线程?
首先,线程和进程不是同一个概念。在多任务系统中,每个独立执行的程序称为“进程”,也就是正在运行的程序。我们现在使用的操作系统一般都是多任务的,即能够同时执行多个应用程序,实际情况是,操作系统负责对CPU等设备的资源进行分配和管理,虽然这些设备某一时刻只能做一件事,但以非常小的时间间隔交替执行多个程序,就可以给人以同时执行多个程序的感觉。
一个进程又可以包含一个或多个线程,一个线程就是一个程序内部的执行线索,如果要程序中实现多个代码段同时交替运行,就需产生多个线程,并指定每个线程上所要运行的程序代码段,这就是多线程。
2、创建线程的两种方式
(1)使用继承Thread的方法
(2)使用实现runnable的方法
3、什么是线程安全?
线程安全就是说多线程访问同一代码,不会产生不确定的结果。编写线程安全的代码是依靠线程同步。同步(synchronized)是以牺牲程序的性能为代价的,使用同步时间延长.
4、关于线程的小知识点
1)如果想让同步方法与同步代码块同步,则同步代码块使用synchronized(this)来使得二者同步,因为同步方法使用的是this来同步的
2)后台线程与前台线程
假设tt是某线程,tt.etDaemon(true)就是把tt设置为后台线程,默认是前台线程。如果程序中只有后台线程,那么循环线程很快就会结束。如果同时存在后台和前台线程,那么线程不会结束。
3)合并线程
pp.join()的作用是把pp所对应的线程合并到调用pp.join();语句的线程中
5、实例
实现功能:生产者Producer传递一个成员给消费者Consumer,Consumer对应输出来,如此往复循环
下面是实现这个功能的两个代码段,区别在哪里呢?
class Producer implements Runnable { Q q = new Q(); public Producer(Q q) { this.q=q; } public void run() { int i = 0; while(true) { synchronized(q) { if(q.bFull) try{q.wait();}catch(Exception e){} if(i == 0) { q.name = "zhangsan"; try{Thread.sleep(1);}catch(Exception e){} q.sex = "male"; } else { q.name = "lisi"; q.sex = "female"; } i = (i+1)%2; q.bFull = true; q.notify(); } } } } class Consumer implements Runnable { Q q = new Q(); public Consumer(Q q) { this.q = q; } public void run() { while(true) { synchronized(q) { if(!q.bFull) try{q.wait();}catch(Exception e){} System.out.print(q.name); System.out.println(":"+ q.sex); q.bFull = false; q.notify(); } } } } class Q { String name = "unknown"; String sex = "unknown"; boolean bFull = false; } class ThreadCommunation { public static void main(String args[]) { try { Q q = new Q(); new Thread(new Producer(q)).start(); new Thread(new Consumer(q)).start(); }catch(Exception e){} } }
class Producer implements Runnable { Q q; Producer(Q q) { this.q = q; } public void run() { int i = 0; while(true) { if(i == 0) q.put("zhangsan","male"); else q.put("lisi","female"); i = (i+1)%2; } } } class Consumer implements Runnable { Q q; Consumer(Q q) { this.q = q; } public void run() { while(true) { q.get(); } } } class Q { private String name = "unknown"; private String sex = "unknown"; private Boolean bFull = false; public synchronized void put(String name,String sex) { if(bFull) try{wait();}catch(Exception e){} this.name = name; this.sex = sex; bFull = true; notify(); } public synchronized void get() { if(!bFull) try{wait();}catch(Exception e){} System.out.print(name + ":"); System.out.println(sex); bFull = false; notify(); } } class ThreadCommunation { public static void main(String args[]) { Q q = new Q(); new Thread(new Producer(q)).start(); new Thread(new Consumer(q)).start(); ThreadTest tt = new ThreadTest(); /*new Thread(tt).start(); for(int i=0;i<100;i++) { if(i == 50) tt.stopMe(); System.out.println("main() is running"); }*/ } }
经过比较,我们可以看出,Q资源,也封装了方法。第二个代码段比第一个更简单,更符合java面向对象的思想,对数据进行private私有化。
Q不仅仅提供数据,还提供了对自己进行操作的方法,解决了线程安全的问题。