线程和进程:操作系统执行多任务,每个任务就是进程;进程执行多任务,每个任务就是线程;包含关系 。

一、多线程创建和启动:

1、继承Thread:重写run()方法,调用start()启动线程。

public class ThreadDemo extends Thread{
        @Override public void run() {
             //具体方法
        }
 }

 

2、实现Runnable接口创建线程类,调用start()启动线程。

public class RunnableDemo implements Runnable {
                public void run() {  
                        //具体方法
              }
}
Thread类其实也实现了Runable接口。
二、线程资源共享。
ThreadDemo类
public class ThreadDemo extends Thread{
          public Integer count = 10;
          public String lock = "lock";
          public ThreadDemo(String name) {
            super(name);
        }
@Override
public void run() {
       synchronized (lock){
                System.out.println(Thread.currentThread().getName() + " is running. count:"+count--);
         }
     }
}
资源不共享:
public class ThreadTest {
public static void main(String[] args) {
//资源不共享
for (int i = 1; i <= 10; i++) {
String name = "t"+i;
new ThreadDemo(name).start();
}
}
}
运行结果:
t4 is running. count:10
t10 is running. count:10
t6 is running. count:10
t1 is running. count:10
t5 is running. count:10
t2 is running. count:10
t8 is running. count:10
t9 is running. count:10
t3 is running. count:10
t7 is running. count:10
资源共享:
public class ThreadTest {
public static void main(String[] args) {
//资源共享
ThreadDemo t = new ThreadDemo("t1");
for (int i = 1; i <= 10; i++) {
new Thread(t).start();
}
}
运行结果:
Thread-0 is running. count:10
Thread-2 is running. count:9
Thread-1 is running. count:8
Thread-7 is running. count:7
Thread-6 is running. count:6
Thread-8 is running. count:5
Thread-3 is running. count:4
Thread-4 is running. count:3
Thread-5 is running. count:2
Thread-9 is running. count:1

三、线程方法

线程的生命周期

有新建(new),就绪(Runnable),运行(Running),阻塞(Blocked)和死亡(Dead)5种状态.

Java中创建多线程实例 java8创建多线程_同步代码块

 

 

3.1 join()和join(long millis),等待join的线程执行完了,被join的线程继续执行。

public class ThreadTest {
public static void main(String[] args) {
try {
ThreadDemo thread1 = new ThreadDemo("thread1");
ThreadDemo thread2 = new ThreadDemo("thread2");
thread1.start();
// thread1.join();
System.out.println("main is running.");
thread2.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
main is running.
thread1 is running.
thread2 is running.
将注释去掉:
运行结果
thread1 is running.
main is running.
thread2 is running.

调用Thread对象的setDaemon(true)方法可将指定线程设置成后台线程.

要将某个线程设置为后台线程,必须在start()之前调用

3.2 线程睡眠sleep(long millis)

sleep()方法比yield()方法有更好的可移植性,通常不建议使用yield()方法来控制并发线程的执行.

3.3 改变线程的优先级

Thread类提供了setPriority(int newPriority)和getPriority()来设置

和返回指定线程的优先级.10最大,1最小,正常为5。

3.4 线程同步

1.synchronized(obj){
}

2.synchronized修饰某个方法或代码块,但不能修饰构造器和成员变量。

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

1、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

2、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

3、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

4、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

5、以上规则对其它对象锁同样适用.

延伸:单线程环境下应该使用StringBuilder来保证较好的性能,当需啊哟保证多线程安全时,

就 应该使用StringBuffer

四、同步锁(Lock)

Lock是控制多个线程对共享资源进行访问的工具.通常,锁提供了对共享资源的独占访问,每次只能有一个

线程对Lock对象加锁,线程开始访问共享资源之前,应该先获得Lock对象.

ReentrantLock锁具有可重入性,也就是说,一个线程可以对已被加锁的ReentrantLock锁再次加锁

ReentrantLock对象会维持一个计数器来追踪lock()方法的嵌套调用,线程在每次调用lock()加锁后,必须显示调用unlock()来释放锁,所以一段被锁包不户的代码可以调用另一个被相同锁保护的方法.

 

public class ThreadDemo extends Thread{
public Integer count = 1;
private final ReentrantLock lock = new ReentrantLock();
public ThreadDemo(String name) {
super(name);
}
@Override
public void run() {
lock.lock();
try {
//执行操作
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
 
}
}

后续:

线程池,死锁,生产者消费者模式,以及线程间通信不再介绍。

由于wait方法是在Object上的,而sleep方法是在Thread上,当用Thread.sleep时,并不能改变对象的状态,因此也不会释放锁

 

 多写代码多读书,做个安静的Coder。