线程、多线程和线程池

开启线程的三种方式?
1)继承Thread类创建线程

2)实现Runnable接口创建线程

3)使用Callable和Future创建线程
Callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。
call()方法可以有返回值
call()方法可以声明抛出异常

线程和进程的区别?
进程是指程序执行时的一个实例。
线程是进程的一个实体。
进程——资源分配的最小单位,线程——程序执行的最小单位。
一个程序至少有一个进程,一个进程至少有一个线程
线程执行开销小,但不利于资源的管理和保护;
而进程正相反。

为什么要有线程,而不是仅仅用进程?
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。
进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。

run()和start()方法区别
start():该方法是在当前线程中启动一个新的线程,而新启动的线程会调用run()方法,同时该方法不能重复调用;
run() :该方法和普通的方法一样,可以重复执行,不会创建新的线程。

public class StartAndRunDemo {
	public static void main(String[] args) {
		Thread t1 = new  MyThread("thread_01");
		System.out.println("run() ....");
		t1.run();
		System.out.println("start() ....");
		t1.start();
		
		//run()方法可以重复执行
		//t1.run();
		//start()方法不能重复执行,重复执行会抛出java.lang.IllegalThreadStateException
		//t1.start();
		
	}
	
	static class  MyThread  extends Thread{
		public  MyThread(String name){
			super(name);
		}
		
		@Override
		public void run() {
			System.out.println(Thread.currentThread().getName() + " is running!");
		}
	}
 
}

输出的结果是:
 run() ....
 main is running!
 start() ....
 thread_01 is running!
 
原文:https://blog.youkuaiyun.com/tianmlin1/article/details/79054304 

①在main方法中执行的run()方法不会创建新的线程,而在main方法中执行的start()方法会启动一个新的线程,新的线程会调用run方法
②run方法可以多次执行,但是start方法不允许多次执行,多次执行start()方法会抛出一个一个运行时异常java.lang.IllegalThreadStateException

如何控制某个方法允许并发访问线程的个数?
使用Semaphore控制某个方法允许并发访问的线程的个数
semaphore.acquire() 请求一个信号量,这时候的信号量个数-1(一旦没有可使用的信号量,也即信号量个数变为负数时,再次请求的时候就会阻塞,直到其他线程释放了信号量)
semaphore.release() 释放一个信号量,此时信号量个数+1

public class SemaphoreTest {
    private Semaphore mSemaphore = new Semaphore(5);
    public void run(){
        for(int i=0; i< 100; i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    test();
                }
            }).start();
        }
    }
 
    private void test(){
        try {
            mSemaphore.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 进来了");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 出去了");
        mSemaphore.release();
    }
}

原文:https://blog.youkuaiyun.com/anhenzhufeng/article/details/70225415 

示例中实例化了具有5个信号量的semaphore,保证只有5个线程在执行test方法

04-18 17:05:46.350 14192-14228/com.tongxt.myapplication I/System.out: Thread-1228 进来了
04-18 17:05:46.351 14192-14231/com.tongxt.myapplication I/System.out: Thread-1231 进来了
04-18 17:05:46.354 14192-14233/com.tongxt.myapplication I/System.out: Thread-1233 进来了
04-18 17:05:46.354 14192-14232/com.tongxt.myapplication I/System.out: Thread-1232 进来了
04-18 17:05:46.355 14192-14234/com.tongxt.myapplication I/System.out: Thread-1234 进来了

04-18 17:05:47.351 14192-14228/com.tongxt.myapplication I/System.out: Thread-1228 出去了
04-18 17:05:47.351 14192-14236/com.tongxt.myapplication I/System.out: Thread-1236 进来了
04-18 17:05:47.352 14192-14231/com.tongxt.myapplication I/System.out: Thread-1231 出去了
04-18 17:05:47.352 14192-14235/com.tongxt.myapplication I/System.out: Thread-1235 进来了
04-18 17:05:47.354 14192-14233/com.tongxt.myapplication I/System.out: Thread-1233 出去了
04-18 17:05:47.354 14192-14237/com.tongxt.myapplication I/System.out: Thread-1237 进来了
04-18 17:05:47.354 14192-14232/com.tongxt.myapplication I/System.out: Thread-1232 出去了
04-18 17:05:47.354 14192-14229/com.tongxt.myapplication I/System.out: Thread-1229 进来了
04-18 17:05:47.356 14192-14234/com.tongxt.myapplication I/System.out: Thread-1234 出去了
04-18 17:05:47.356 14192-14230/com.tongxt.myapplication I/System.out: Thread-1230 进来了
04-18 17:05:48.351 14192-14236/com.tongxt.myapplication I/System.out: Thread-1236 出去了

在Java中wait和seelp方法的不同;
一.java中的sleep()和wait()的区别;

对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

在调用sleep()方法的过程中,线程不会释放对象锁。

而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

public class TestD {

    public static void main(String[] args) {
        new Thread(new Thread1()).start();
        try {
            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        new Thread(new Thread2()).start();
    }

    private static class Thread1 implements Runnable {
        @Override
        public void run() {
            synchronized (TestD.class) {
                System.out.println("enter thread1...");
                System.out.println("thread1 is waiting...");
                try {
                    // 调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池
                     TestD.class.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("thread1 is going on ....");
                System.out.println("thread1 is over!!!");
            }
        }
    }

    private static class Thread2 implements Runnable {
        @Override
        public void run() {
            synchronized (TestD.class) {
                System.out.println("enter thread2....");
                System.out.println("thread2 is sleep....");
                // 只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
                TestD.class.notify();
                // ==================
                // 区别
                // 如果我们把代码:TestD.class.notify();给注释掉,即TestD.class调用了wait()方法,但是没有调用notify()
                // 方法,则线程永远处于挂起状态。
                try {
                    // sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,
                    // 但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
                    // 在调用sleep()方法的过程中,线程不会释放对象锁。
                    Thread.sleep(5000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("thread2 is going on....");
                System.out.println("thread2 is over!!!");
            }
        }
    }
}

这个没有注解掉:TestD.class.notify()的图片
在这里插入图片描述

这是注解掉TestD.class.notify()的图片;
在这里插入图片描述
这时候thread1 一直处在挂起的状态

谈谈wait/notify关键字的理解

什么导致线程阻塞?
A、线程执行了Thread.sleep(int millsecond);方法,当前线程放弃CPU,睡眠一段时间,然后再恢复执行

B、线程执行一段同步代码,但是尚且无法获得相关的同步锁,只能进入阻塞状态,等到获取了同步锁,才能回复执行。

C、线程执行了一个对象的wait()方法,直接进入阻塞状态,等待其他线程执行notify()或者notifyAll()方法。

D、线程执行某些IO操作,因为等待相关的资源而进入了阻塞状态。比如说监听system.in,但是尚且没有收到键盘的输入,则进入阻塞状态。

线程如何关闭?
https://blog.youkuaiyun.com/moonpure/article/details/80414104

讲一下java中的同步的方法
https://www.cnblogs.com/jiansen/p/7351872.html

数据一致性如何保证?

如何保证线程安全?

如何实现线程同步?

两个进程同时要求写或者读,能不能实现?如何防止进程的同步?

线程间操作List
分段操作
https://www.cnblogs.com/huangdabing/p/9251598.html

Java中对象的生命周期
https://www.cnblogs.com/mengfanrong/p/4007456.html

Synchronized用法

synchronize的原理

谈谈对Synchronized关键字,类锁,方法锁,重入锁的理解
https://blog.youkuaiyun.com/u012545728/article/details/80843595

static synchronized 方法的多线程访问和作用

同一个类里面两个synchronized方法,两个线程同时访问的问题

volatile的原理

谈谈volatile关键字的用法

谈谈volatile关键字的作用

谈谈NIO的理解

synchronized 和volatile 关键字的区别

synchronized与Lock的区别

ReentrantLock 、synchronized和volatile比较

ReentrantLock的内部实现

lock原理

死锁的四个必要条件?

怎么避免死锁?

对象锁和类锁是否会互相影响?

什么是线程池,如何使用?

Java的并发、多线程、线程模型

谈谈对多线程的理解

多线程有什么要注意的问题?

谈谈你对并发编程的理解并举例说明

谈谈你对多线程同步机制的理解?

如何保证多线程读写文件的安全?

多线程断点续传原理
https://blog.youkuaiyun.com/qq_32101859/article/details/53177428
https://blog.youkuaiyun.com/owenchan1987/article/details/77688484

断点续传的实现

五)并发编程有关知识点

(这个是一般Android开发用的少的,所以建议多去看看):
平时Android开发中对并发编程可以做得比较少,Thread这个类经常会用到,但是我们想提升自己的话,一定不能停留在表面,,我们也应该去了解一下java的关于线程相关的源码级别的东西。

学习的参考资料如下:

Java 内存模型
java线程安全总结
http://www.iteye.com/topic/806990
深入理解java内存模型系列文章
http://ifeve.com/java-memory-model-0/

线程状态:
一张图让你看懂JAVA线程间的状态转换
https://my.oschina.net/mingdongcheng/blog/139263

锁:
锁机制:synchronized、Lock、Condition
http://blog.youkuaiyun.com/vking_wang/article/details/9952063
Java 中的锁
http://wiki.jikexueyuan.com/project/java-concurrent/locks-in-java.html

并发编程:
Java并发编程:Thread类的使用
http://www.cnblogs.com/dolphin0520/p/3920357.html
Java多线程编程总结
http://blog.51cto.com/lavasoft/27069
Java并发编程的总结与思考
https://www.jianshu.com/p/053943a425c3#
Java并发编程实战—–synchronized
http://www.cnblogs.com/chenssy/p/4701027.html
深入分析ConcurrentHashMap
http://www.infoq.com/cn/articles/ConcurrentHashMap#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值