Java线程基础知识

1,两种方法来创建线程:

1)继承Thread类实现run方法:

public class Hello1extends Thread
{
    String name;
     
    public Hello1(String n)
    {
        name = n;
    }
     
    public void run()
    {
        for (int i=1; i<=10; i++)
        {
            System.out.println(name+" Hello "+i);
        }
    }
}


2)实现Runnable接口,实现run方法:

public class Hello2implements Runnable
{
    String name;
     
    public Hello2(String n)
    {
        name = n;
    }
     
    public void run()
    {
        for (int i=1; i<=10; i++)
            System.out.println(name+" Hello "+i);
    }
}


推荐第二种方法;

2,产生Thread对象和启动线程

public class ThreadsExample1
{
    public static void main(String argv[])
    {
        Hello1 h1 = new Hello1("Thread1");
        Hello2 h2 = new Hello2("Thread2");
         
        Thread t1 = new Thread(h1);
        Thread t2 = new Thread(h2);
         
        t1.start();
        t2.start();
    }
}


3,停止线程运行

下面的run方法可以让线程一直运行:

public class Hello3implements Runnable
{
    String name;
     
    public Hello3(String n)
    {
        name = n;
    }
     
    public void run()
    {
        int i=0;
         
        while(true)//这样来写run方法
        {
            i++;
            System.out.println(name+" Hello "+i);
        }
    }
}


加一个循环条件来达到停止现成的效果:

public class Hello4implements Runnable
{
    String name;
    Boolean isStop;
    public Hello4(String n)
    {
        name = n;
        isStop = false;
    }
     
    public void run()
    {
        int i=0;
         
        while(!isStop)
        {
            i++;
            System.out.println(name+" Hello "+i);
        }
    }
     
    public void stop()//控制条件
    {
        isStop = true;
    }
}


当一个线程对象进入死亡状态后,就没有任何方法可以回到其他状态。

4,暂停线程运行

sleep方法:

yield方法

join方法,

来看join的一个例子:

package ch22;
 
public class MotherThreadimplements Runnable
{
    public void run()
    {
        System.out.println("妈妈准备煮饭");
        System.out.println("妈妈发现米酒用完了");
        System.out.println("妈妈叫儿子去买米酒");
         
        Thread son = new Thread(new SonThread());
        son.start();
         
        System.out.println("妈妈等待儿子把米酒买回来");
         
        try {
            son.join();
        }
        catch (InterruptedException ie)
        {
            System.err.println("发生异常!");
            System.err.println("妈妈中断煮饭");
            System.exit(1);
        }
         
        System.out.println("妈妈开始煮饭");
        System.out.println("妈妈煮好饭了");
    }
}


SonThread:

package ch22;
 
public class SonThreadimplements Runnable
{
    public void run()
    {
        System.out.println("儿子出门去买米酒");
        System.out.println("儿子买东西来回需5分钟");
         
        try {
            for (int i=1; i<=5; i++)
            {
                Thread.sleep(1000);
                System.out.print(i+"分钟 ");
            }
        }
        catch (InterruptedException ie)
        {
            System.err.println("儿子发生意外");
        }
         
        System.out.println("\n儿子买米酒回来了");
    }      
}

package ch22;
 
public class Cooking
{
    public static void main(String argv[])
    {
        Thread mother = new Thread(new MotherThread());
        mother.start();
    }
}



运行结果:

5,数据同步处理

现在我们有这样一个线程:

package ch22;
 
public class ShareDataimplements Runnable
{
    int i;
 
    public void run()
    {
        while (i<10)
        {
            i++;
            for(int j=0; j<10000000; j++);
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}


现在我们来产生两个ShareData对象,并给两个Thread运行

package ch22;
 
public class ThreadsExample2
{
    public static void main(String argv[])
    {
        ShareData s1 = new ShareData();
        ShareData s2 = new ShareData();
         
        Thread t1 = new Thread(s1);
        Thread t2 = new Thread(s2);
         
        t1.start();
        t2.start();
    }
}


其结果如图:

可以看到,两个Thread对象在交互运行,Thread 0和Thread 1分别从0按顺序到10.

这是因为两个Thread共用了程序代码但是没有共用数据,下面我们来看程序代码和数据都共用的效果

package ch22;
 
public class ThreadsExample3
{
    public static void main(String argv[])
    {
        ShareData s = new ShareData();
        Thread t1 = new Thread(s);//两个小成共用一个对象ShareData
        Thread t2 = new Thread(s);
         
        t1.start();
        t2.start();
    }
}


结果并不是你所想象的从0到10,而是:

这是为什么呢????

这是因为线程被分割运行了,具体分析略。

6,synchronized实现线程同步

synchronized(要取得锁的对象)

{

  要锁定的代码

}

package ch22;
 
public class SyncShareData implements Runnable
{
    int i;
     
    public void run()
    {
        while (i<10)
        {
            /*锁的对象是SyncShareData自己,也就是说这个对象对应的线程要进行同步机制*/
            synchronized(this)
            {
                i++;
                for(int j=0; j<10000000; j++);
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}


package ch22;
 
public class ThreadsExample4
{
    public static void main(String argv[])
    {
        SyncShareData s = new SyncShareData();
        /*t1和t2都是操作同一个SyncShareData对象的线程,
         * 要进行同步机制,因为SyncShareData实现了锁机制*/
        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
         
        t1.start();
        t2.start();
    }
}



实现了两个线程对同一个对象操作的同步

7,等待wait与通报notify

生产者和消费者的例子:

package ch22;
 
public class Storage
{
    private int count;//当前库存值
    private int size;//最大库存量
     
    public Storage(int s)
    {
        size = s;
    }
     
     
    //类里的方法实现了锁,则调用这个方法必须取得这个类的对象的锁
    public synchronized void addData(String n)
    {
        while (count == size)//注意为什么要用while循环而不是if
        {
            try {
                this.wait();//进入等待状态
            }
            catch (InterruptedException e) { }
        }
         
        this.notify();//通知消费者可以消费了
        count++;
        System.out.println(n+" make data count: "+count);
    }
     
     
    public synchronized void delData(String n)
    {
        while (count == 0)
        {
            try {
                this.wait();
            }
            catch (InterruptedException e) { }
        }
         
        this.notify();
        System.out.println(n+" use data count: "+count);
        count--;
    }   
}


package ch22;
 
public class Producer extends Thread
{
    private String name;
    private Storage s;
     
    public Producer(String n, Storage s)
    {
        name = n;
        this.s = s;
    }
     
    public void run()
    {
        while (true)
        {
            s.addData(name);
 
            try {
                sleep((int)Math.random()*3000);
            }
            catch (InterruptedException e) { } 
        }
    }
}



package ch22;
 
public class Consumer extends Thread
{
    private String name;
    private Storage s;
     
    public Consumer(String n, Storage s)
    {
        name = n;
        this.s = s;
    }
     
    public void run()
    {
        while (true)
        {
            s.delData(name);
             
            try {
                sleep((int)Math.random()*3000);
            }
            catch (InterruptedException e) { } 
        }
    }
}


package ch22;
 
public class ThreadsExample5
{
    public static void main(String argv[])
    {
        Storage s = new Storage(3);
        Producer p1 = new Producer("Producer1", s);
        Producer p2 = new Producer("Producer2", s);
        Consumer c1 = new Consumer("Consumer1", s);
         
        p1.start();
        p2.start();
        c1.start();
         
    }
}

package ch22;
 
public class Storage
{
    private int count;//当前库存值
    private int size;//最大库存量
     
    public Storage(int s)
    {
        size = s;
    }
     
     
    //类里的方法实现了锁,则调用这个方法必须取得这个类的对象的锁
    public synchronized void addData(String n)
    {
        while (count == size)//注意为什么要用while循环而不是if
        {
            try {
                this.wait();//进入等待状态
            }
            catch (InterruptedException e) { }
        }
         
        this.notify();//通知消费者可以消费了
        count++;
        System.out.println(n+" make data count: "+count);
    }
     
     
    public synchronized void delData(String n)
    {
        while (count == 0)
        {
            try {
                this.wait();
            }
            catch (InterruptedException e) { }
        }
         
        this.notify();
        System.out.println(n+" use data count: "+count);
        count--;
    }  
}

package ch22;
 
public class Producerextends Thread
{
    private String name;
    private Storage s;
     
    public Producer(String n, Storage s)
    {
        name = n;
        this.s = s;
    }
     
    public void run()
    {
        while (true)
        {
            s.addData(name);
 
            try {
                sleep((int)Math.random()*3000);
            }
            catch (InterruptedException e) { } 
        }
    }
}


package ch22;
 
public class Consumerextends Thread
{
    private String name;
    private Storage s;
     
    public Consumer(String n, Storage s)
    {
        name = n;
        this.s = s;
    }
     
    public void run()
    {
        while (true)
        {
            s.delData(name);
             
            try {
                sleep((int)Math.random()*3000);
            }
            catch (InterruptedException e) { } 
        }
    }
}

package ch22;
 
public class ThreadsExample5
{
    public static void main(String argv[])
    {
        Storage s = new Storage(3);
        Producer p1 = new Producer("Producer1", s);
        Producer p2 = new Producer("Producer2", s);
        Consumer c1 = new Consumer("Consumer1", s);
         
        p1.start();
        p2.start();
        c1.start();
         
    }
}



.........

Producer1 make data count: 3
Consumer1 use data count: 3
Consumer1 use data count: 2
Producer1 make data count: 2
Consumer1 use data count: 2
Producer1 make data count: 2

.........

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值