码迷,mamicode.com
首页 > 编程语言 > 详细

java 多线程

时间:2014-09-27 17:04:30      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   使用   ar   java   数据   sp   

1. 后台线程:

   如果在某个线程运行之前调用了setDaemon方法,则该线程就变为后台线程。

   对java程序来说,只要还有一个前台线程在运行,这个进程就不会结束,如果一个进程只有后台线程在运行,这个进程就会结束。

public class TestSetDaemon {
    public static void main(String[] args) {
        Thread th = new Thread(new ThreadTest());
        //th.setDaemon(true);
        th.start();
    }
}
class ThreadTest implements Runnable{
    public void run(){
        while(true){
            System.out.println("threadtest is running");
        }
    }
}

2. 联合线程:
thread.join()作用是把thread所对应的线程合并到调用thread.join()语句的线程中。

public class TestJoin {
    public static void main(String[] args) {
        Thread th=new Thread(new JoinThread());
        th.start();
        int i=1;
        while(true){
            i++;
            if(i==100)
                th.join(10000);
            System.out.println("main***************");
            Thread.sleep(100);
        }
    }
}
class JoinThread implements Runnable{
    public void run(){
        while(true){                
                        Thread.sleep(100);
            System.out.println("threadtest is running");
        }
    }
}

3.继承Thread与Runnable接口的区别:
   适合多个相同的程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码、数据有效分离,较好的体现了面向对象的设计思想。

public class ExtendsThread {
    public static void main(String[] args) {
        Thread th1=new Tick();
        Thread th2=new Tick();
        th1.start();
        th2.start();
    }
}
class Tick extends Thread{
    public static int count=100;   //必须是全局
    public void run(){
        while(count>0){
        System.out.println(Thread.currentThread()+"*****"+(count--));
    }
    }
}

public class ImplemtRunnable {
    public static void main(String[] args) {
        Ticket t = new Ticket();
        Thread th1 = new Thread(t);
        Thread th2 = new Thread(t);
        th1.start();
        th2.start();
    }
}
class Ticket implements Runnable{
    int count=100;
    public void run(){
        while(count>0){
            System.out.println(Thread.currentThread()+"***"+(count--));
        }
    }
}

线程同步:sychronized关键字的原理:任何一个对象都有一个标志位,它有0,1两种状态,开始状态为1,当线程执行到含有sychronized的关键字时就会检查它所带的对象的标志位是1还是0,如果标志位为1,则能继续向下执行,同时将对象的标志位置0。如果对象的标志位为0,线程就会阻塞,将它放在该对象的阻塞队列中,一直等到该标志位为1,才从该对象的阻塞队列中取出一个等待的线程,继续执行。我们的线程在加上sychronized关键字后,并不能决定CPU的调度问题,只是在标志位为0时,不能继续执行,这样可以保证在一段时间内,该代码段只被一个线程访问,从而保证线程安全。

public void run(){
    while(true){
    if(count>0){//要保证这条语句的原子性
        try {Thread.sleep(100);} catch (InterruptedException e) {}
        System.out.println(Thread.currentThread()+"*******"+(count--));
    }
   }
}
//同步代码块
class Ticket implements Runnable{
    int count=100;
    String str=new String();   //同步对象定义不能放在run方法中,因为每个对象在调用run方法时都会产生一个新的同步对象,并不是同一个监视器对象
    public void run(){
         while(true){
             synchronized (str) {
              if(count>0){//通过synchronized保证这条语句的原子性
              try {Thread.sleep(100);} catch (InterruptedException e) {}
              System.out.println(Thread.currentThread()+"****"+(count--));
         }
    }
     }
}    
//同步方法
class Ticket implements Runnable{
    int count=100;
    public void run(){
         while(true){
        this.sale();
        }
    }
    public synchronized void sale(){
        if(count>0){//要保证这条语句的原子性
        try {Thread.sleep(100);} catch (InterruptedException e) {}
        System.out.println(Thread.currentThread()+"***"+(count--));
       }
    }
}
//方法与代码块同步
public class ImplemtRunnable {
    public static void main(String[] args) throws InterruptedException {
        Ticket t = new Ticket();
        Thread th1 = new Thread(t);
        th1.start();
        Thread.sleep(100);  //确保在th2运行之前th1已经启动
        Thread th2 = new Thread(t);
        t.str=new String("methord");
        th2.start();
    }
}  
class Ticket implements Runnable{
    int count=100;
    String str=new String();
    public void run(){
        if(str.equals("methord")){
        while(true){
            this.sale();
        }
       }else{
        while(true){
            synchronized (this) {
            if(count>0){//要保证这条语句的原子性
                try {Thread.sleep(100);} catch () {}
                    System.out.println(Thread.currentThread().getName()+"******block*****"+(count--));
            }
        }
                
    }
    }    
    }
    public synchronized void sale(){
        if(count>0){//要保证这条语句的原子性
            try {Thread.sleep(100);} catch (InterruptedException e) {}
            System.out.println(Thread.currentThread()+"*******methord*****"+(count--));
        }
    }
}

线程死锁:线程A得到监视器1,而同时请求监视器2;线程B得到了监视器2,而同时请求监视器1
synchronized(str1){                          synchronized(str2){   

  synchronized(str2){                            synchronized(str1){  

  }                                                       }

}                                                      }

多个线程访问同一数据时就会发生线程安全问题,就必须实现对原子性的操作进行同步操作(要使用同一个监视器)。

public void push(char c)

{  //两个线程同时访问时  线程1进入push方法时,index=2,线程1将c放在data[2]中,还没来得急进行index++。CPU此时又调度线程2执行,此时index仍为2,线程2又将数据放在data[2]中,就会导致在此位置放置了两次数据,而index=3中没有数据。

  data[index]=c;  index++;

}

java 多线程

标签:style   blog   color   io   使用   ar   java   数据   sp   

原文地址:http://www.cnblogs.com/java-cjt/p/3996425.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!