java多线程

2016-02-07  本文已影响39人  onweer

多线程

优点: 解决一个进程同时执行多个代码任务的问题


自定义线程

方法1: 继承Thread

  1. 自定义一个雷继承Thread
  2. 重写Threadrun()方法,多线程代码在run()中执行
  3. 创建Thread子类对象,并调用start()方法启动一个线程.
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }
    }
}
class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(super.getName() + i);
        }
    }

Console

main0
Thread-00
main1
Thread-01
main2
Thread-02
main3

方法2: 实现Runnable接口

  1. 自定义一个类implements Runnable接口
  2. 实现Runnable接口中的run()方法,把自定义线程的任务代码定义在run()方法中
  3. 创建Runnable实现类的对象
  4. 创建Thread对象,并把Runnable实现类的对象作为参数传递
  5. 调用Thread对象的start()方法开启线程
public static void main(String[] args) {
        //MyThread myThread = new MyThread();
        //myThread.start();
        MyThread2  myThread2 = new MyThread2();
        Thread th = new Thread(myThread2);
        th.start();
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }
    }
class MyThread2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }   
    }
}

Console

main0
Thread-00
main1
Thread-01
main2
Thread-02


线程安全

弊端:多个线程需要判断锁,较为消耗资源

线程安全出现问题原因:

1.必须存在两个或以上的线程共享着一个资源.
2.操作共享资源的代码必须有两句或者两句以上.

1.同步代码块

synchronized(对象){//这个对象可以是任意对象
//需要被同步的代码
//对象如同锁,持有锁的线程可以在同步中执行 
//没持有锁的线程即使获取CPU的执行权,也进不去 
}
    public static void main(String[] args) {
        //MyThread myThread = new MyThread();
        //myThread.start();
        MyThread2  myThread2 = new MyThread2();
        Thread th1 = new Thread(myThread2);
        Thread th2 = new Thread(myThread2);
        Thread th3 = new Thread(myThread2);
        Thread th4 = new Thread(myThread2);
        th1.start();
        th2.start();
        th3.start();
        th4.start();
    }
class MyThread2 implements Runnable{
    Object obj = new Object();
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            synchronized (obj) {
                System.out.println(Thread.currentThread().getName() +","+ i);
            }
            
        }   
    }
}

Console

Thread-0,0
Thread-0,1
Thread-0,2
Thread-2,0
Thread-2,1
Thread-2,2
Thread-1,0
Thread-1,1
Thread-1,2
Thread-3,0
Thread-3,1
Thread-3,2

2.同步函数

修饰符 synchronized 返回值类型 函数名(形参列表...){
}
class Bank{
    private int sum = 0;
    public synchronized void add(int a){//同步函数
        sum += a;
        try{
            Thread.sleep(40);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("sum = " + sum);
    }
}
class Client implements Runnable{
    private Bank b = new Bank();
    @Override
    public void run(){
        for (int i = 0; i < 3; i++) {
            b.add(100);
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        Client c = new Client();
        Thread t1 = new Thread(c);  
        Thread t2 = new Thread(c);  

        t1.start();  
        t2.start();  
     
    }

注意 :

  1. 同步代码的锁,可以是任意对象Object,同步函数的锁,是固定的,非静态函数的锁对象是this ,静态函数的锁对象是class对象
  2. 同步锁对象必须是多线程共享的对象,否则锁不住(锁唯一)
  3. 再同步代码块或者同步函数中调用sleep方法不会释放锁对象,调用 wait方法是会释放对象的。

给个github follow me的链接,上面有很多初学者可供学习的资料,项目.

<a>https://github.com/SuperZee</a>

上一篇下一篇

猜你喜欢

热点阅读