Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java多线程 #9

Open
huangchucai opened this issue Feb 21, 2019 · 0 comments
Open

Java多线程 #9

huangchucai opened this issue Feb 21, 2019 · 0 comments

Comments

@huangchucai
Copy link
Owner

huangchucai commented Feb 21, 2019

多线程

基本概念

进程:程序运行时所占有的所有的资源的总称或者说容器
线层: 程序执行的基本单元

创建线程方式

1. 实现Runnable接口
  • 实现Runnable接口

  • 重写run方法 -> 可以调用其他类,申明变量

  • 在类中实例化一个线程对象 new Thread(Runnable threadOb, String threadName)

  • 创建后,必须调用start()才可以运行

    public class RunnableDemo implements Runnable {
        private String threadName; // 线程姓名
        private Thread t; // 线程
    
        RunnableDemo(String name) {
            threadName = name;
            System.out.println("线程开始,初始化完成");
        }
    
        @Override
        public void run() {
            System.out.println("Running" + threadName);
            try {
                for (int i = 4; i > 0; i--) {
                    System.out.println("Thread: " + threadName + ", " + i);
                    // 让线程睡眠一会
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                System.out.println("Thread " + threadName + " interrupted.");
            }
            System.out.println("Thread " + threadName + " exiting.");
        }
    
        public void start() {
            System.out.println("Starting " + threadName);
            if (t == null) {
                // 创建线程
                t = new Thread(this, threadName);
                // 线程开始,会直接运行重写的run方法
                t.start();
            }
        }
    }
    
    // 调用
    public class TestThread {
        public static void main(String args[]) {
            RunnableDemo R1 = new RunnableDemo("hcc");
            R1.start();
        }
    }
2. 通过继承Thread
  1. 继承Thread

  2. 重写run方法

    public class ThreadDemo extends Thread {
        private Thread t;
        private String threadName;
    
        ThreadDemo(String name) {
            threadName = name;
            System.out.println("线程开始,初始化完成");
        }
    
        public void run() {
            System.out.println("ThreadDemo" + threadName);
            try {
                for (int i = 4; i > 0; i--) {
                    System.out.println("Thread: " + threadName + ", " + i);
                    // 让线程睡眠一会
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                System.out.println("Thread " + threadName + " interrupted.");
            }
            System.out.println("Thread " + threadName + " exiting.");
        }
    
        public void start() {
            System.out.println("Starting " + threadName);
            if (t == null) {
                // 创建线程
                t = new Thread(this, threadName);
                // 线程开始,会直接运行重写的run方法
                t.start();
            }
        }
    }

同步

当我们创建了两个或两个以上的线程需要共享资源,它们需要一个方法来确定资源在某一刻仅被一个线程占用,而不用出现资源混乱的情况,达到这个目的的过程叫做同步synchronized

使用方法

  • 修饰语句块
  • 修饰方法
synchronized void get() {
	*****    
}
// 等价于
void get() {
    synchronized(this) {
        
    }
}
特点
  1. synchronized是针对对象级别的,同一个类的不同方法,加上synchronized, 会竞争对象

    package test16;
    
    // A correct implementation of a producer and consumer.
    class Q {
        //仓库
        int n = 0;
        boolean valueSet = false;
    
        //消费者
        // synchronized void get() === void get() { synchronized(this) {} }
        synchronized int get() {
            // value 还没有被设置好!或者仓库数量没有
            if (!valueSet) {
                try {
                    wait(); // 暂停, 等待着put()来设置好这个值只后再读取
                } catch (InterruptedException e) {
                    System.out.println("InterruptedException caught");
                }
            }
            System.out.println("Got: " + n);
            valueSet = false; // 标记已经取走了值
            notify(); // 通知put()可以设置另外一个值了
            return n;
        }
    
        //生产者
        synchronized void put(int n) {
            // 如果这个值已经设置好了
            if (valueSet)
                try {
                    wait(); // 等待get()把值取走
                } catch (InterruptedException e) {
                    System.out.println("InterruptedException caught");
                }
            this.n = n; //设置一个新的值
            valueSet = true; // 标记已经设置好了
            System.out.println("Put: " + n);
            notify(); // 通知线程get() 这个最新的值
        }
    
    }
    
    
    Q q = new Q()

    总结:当Q 的实例被多个线程使用的时候,如果线程调用了synchronized的方法,q就会被作为竞争对象(所有的线程(t1/t2/t3/t4)共享了同一个Q,调用这个Q的任何synchronized方法全部都会将这个Q对象作为锁进行竞争)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant