多线程
优点: 解决一个进程同时执行多个代码任务的问题
自定义线程
方法1: 继承Thread
- 自定义一个雷继承
Thread
类 - 重写
Thread
的run()
方法,多线程代码在run()
中执行 - 创建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
接口
- 自定义一个类
implements Runnable
接口 - 实现
Runnable
接口中的run()
方法,把自定义线程的任务代码定义在run()
方法中 - 创建
Runnable
实现类的对象 - 创建
Thread
对象,并把Runnable
实现类的对象作为参数传递 - 调用
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();
}
注意 :
- 同步代码的锁,可以是任意对象
Object
,同步函数的锁,是固定的,非静态函数的锁对象是this
,静态函数的锁对象是class
对象 - 同步锁对象必须是多线程共享的对象,否则锁不住(锁唯一)
- 再同步代码块或者同步函数中调用
sleep
方法不会释放锁对象,调用wait
方法是会释放对象的。
给个github follow me的链接,上面有很多初学者可供学习的资料,项目.
<a>https://github.com/SuperZee</a>
网友评论