创建线程的两种方式:
1,extends Thread
2. implements Runnable
两者的区别:http://blog.csdn.net/michellehsiao/article/details/7639788
我们稍作总结:
1、Runnable适合于多个相同程序代码线程去处理统一资源的情况,把虚拟的cpu(线程)同程序的代码,数据有效分离,较好体现面向对象的编程的思想
2、Runnable可以避免由于java的单继承机制带来的局限。可以再继承其他类的同时,还能实现多线程的功能。( Java 编程语言只允许一个类有一个父类。同时,某些程序员避免从 Thread 类导出,因为它强加了类层次。对于这种情况,就要 runnable 接口)
3、Runnable能增加程序的健壮性。代码能够被多个线程共享。
下面我们简单看一个实现Runnable接口的多线程
class Demo{
public void run(){
show();
}
public void show(){
//功能实现
}
}
class ThreadDemo{
public static void main(String[] args){
Demo d= new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t2.start();
}
}
在使用线程过程中我们会遇到很多问题,线程同步就是其中之一。接下来,我们要对多线程进行进一步了解(来自传智播客)
需求一:两个储户到银行存钱,每次存100,一共存3次(线程同步)
//两个储户到银行存钱,每次存100,共存3次
class Bank{
private int sum;
//同步函数
private synchronized void add(int num){
sum = sum + num;
try{
Thread.sleep(10);
}catch(InterruptedException e){
e.printStack();
}
System.out.println("sum="+sum);
}
/*
同步代码块
private Object obj = new Object();
public void add(int num){
synchronized(obj){
sum = sum + num;
try...
}
}
*/
}
class Custom implements Runnable{
private Bank b = new Bank();
public void run(){
for(int x=0;x<3;x++){
b.add(100);
}
}
}
class BankDemo{
public static void main(String[] args){
Custom c = new Custom();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
通过这个需求的实现,我们可以看到线程同步的方式可以使用同步函数或同步代码块。线程加锁以后可以保证其运行的一致性。
同步函数的锁是:this
同步的好处:解决了线程的安全问题;
同步的弊端:相对降低了效率,因为同步外的线程都会判断同步锁;
同步的前提:同步中必须有多个线程并使用同一个锁。
我们在刚才的需求实现中使用了同步函数,如果此时的同步函数被static修饰,结果会如何?
我们使用一个卖票的案例来查看
class Ticket implements Runnable{
private static int num =100;
boolean flag = true;
StaticLock sl = new StaticLock();
public void run(){
if(flag){
while(true){
//错误情况,static同步函数的锁不是this,而是this.getClass()
// synchronized(this){
synchronized(this.getClass()){
if(num>0){
System.out.println(Thread.currentThread().getName()+"....obj...."+num--);
}
}
}
}else{
while(true){
sale();
}
}
}
public static synchronized void sale(){
if(num>0){
System.out.println(Thread.currentThread().getName()+"....obj...."+num--);
}
}
}
class StaticSynchronizedFunctionDemo{
public static void main(String[] args){
Ticket t =new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{
Thread.sleep(10);
}catch(InterruptedException e){
}
t.flag = false;
t2.start();
}
}
在使用同步机制的使用,要确保锁的唯一性!