您的位置:首页 > 编程语言 > Java开发

Java多线程总结(一)

2015-06-30 16:38 435 查看
1.多线程的优势:同时运行多部分代码;劣势:效率降低。JVM在启动的时候,至少启动了两个线程,执行main函数的线程,垃圾回收线程。

2.垃圾回收机制,System.gc()方法告诉JVM调用finalize方法,但不一定立即执行。

3.创建线程的方式:第一种:继承Thread类。示例如下:

package heima.person.caizhanqi.basetest;

public class ThreadDemo extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for (int i = 0; i < 10; i++) {
System.out.println(
Thread.currentThread().getName()
+"-----------"+this.getId());
}
}
public static void main(String[] args) {

new ThreadDemo().start();
for (int i = 0; i < 10; i++) {
+"-----------"
+Thread.currentThread().getId());
}
new ThreadDemo().start();
new ThreadDemo().start();
}
}


.

4.第二种:实现Runnable接口:优点:将线程的任务从线程的子类中分离出来,进行了单独的封装,按照面向对象的思想将任务封装成对象。示例如下:

public class ThreadDemo implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()
+ "--------"+ i + "--------"
+ Thread.currentThread().getId());
}
}

public static void main(String[] args) {
ThreadDemo demo = new ThreadDemo();
new Thread(demo).start();
new Thread(demo).start();
new Thread(demo).start();
}

}


.

5.Thread类,Runnable接口模拟实现,如下:

public class ThreadDemo{
private Runnable r;
public ThreadDemo(){

}
public ThreadDemo(Runnable r){
this.r = r;
}

public void run(){
if(r!=null)
r.run();
}

public void start(){
run();
}

}


.

6.线程安全问题示例:

public class ThreadSecurity implements Runnable {
private int num;

public ThreadSecurity() {
// TODO Auto-generated constructor stub
}

public ThreadSecurity(int num) {
this.num = num;
}

@Override
public void run() {
while (num > 0) {
try {
System.out.println(
Thread.currentThread().getName()
+ "----sale..."+ num);
num--;
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
}
}

public static void main(String[] args) {
ThreadSecurity t = new ThreadSecurity(10);
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
}


.

7.线程安全问题产生的原因:1.多个线程在操作共享的数据;2.操作共享数据的线程代码有多条。由此可知,当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。

8.解决线程安全问题的方案:将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程不能参与运算。必须要当前线程把这些代码都执行完毕,其他线程才能参与运算。

9.同步代码块:修饰词:synchronized.同步的好处:解决了线程的安全问题;弊端:当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中降低程序运行的效率。同步的前提:必须有多个线程使用同一个锁。

10.Synchroized修饰的函数锁是this,修饰的静态变量,锁是类的字节码文件,修饰的成员变量,锁可以是任意对象。

11.同步示例:

public class ThreadSynchronized implements Runnable {
private int num;
private boolean flag;
public ThreadSynchronized() {
flag = true;
num = 100;
}

@Override
public void run() {
if (flag) {
while (true) {
synchronized (this) {
if (num > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
Thread.currentThread().getName()
+ "--true--" + num--);
}
}
}
} else {
while (true)
show();
}
}
public synchronized void show() {
if (num > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
Thread.currentThread().getName() + "--flase--"
+ num--);
}
}
public static void main(String[] args) {
ThreadSynchronized ts = new ThreadSynchronized();
new Thread(ts).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ts.flag = false;
new Thread(ts).start();
new Thread(ts).start();
}
}


.

12.多线程下的单例设计模式:1.饿汉式:不存在多个线程共同操作数据的情况,线程安全。

class SingleThread{
private static final SingleThread s = new SingleThread();
private SingleThread(){}
public SingleThread getSingleThread(){
return s;
}
}


2.懒汉式:存在线程安全问题。

Class SingleThread{
private static final SingleThread s = null;
Private SingleThread(){}
public SingleThread getSingleThread(){
if(s == null){
sysnchronized(SingleThread.class){
if(s == null){
S = new SingleThread();
}
}
}
return s;
}
}


.

13.死锁:想要获取的锁被别的线程所占有,互相不释放,导致程序不能继续执行下去。死锁示例:

public class DeadLock implements Runnable {
private int num = 1000;
private boolean flag;
private Object obj = new Object();
@Override
public void run() {
if (flag) {
while (true) {
synchronized (obj) {
if (num > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
Thread.currentThread().getName()
+ "--true--" + num--);
}
show();
}
}
} else {
while (true) {
show();
}
}
}
public synchronized void show() {
synchronized (obj) {
if (num > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "--false--" + num--);
}
}
}
public static void main(String[] args) {
DeadLock dl = new DeadLock();
dl.flag = true;
new Thread(dl).start();
new Thread(dl).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dl.flag = false;
new Thread(dl).start();
}
}


.

14.多线程间的通信:多个线程在处理统一资源,但是任务不同,这时就需要多线程间的通信。等待/唤醒机制涉及的方法:1.wait(),让线程处于冻结状态,被wait()的线程会放在线程池中;2.notify(),唤醒线程池中的一个线程;3.notifyAll(),唤醒线程池中的所有线程。PS:wait释放执行权,释放锁。以上三个方法都定义在同步中,因为这些方法是用于操作线程状态的方法。

15.一对一的线程通信,线程被唤醒之后,会继续从之前wait的部分之后开始执行任务。一对一线程通信如下:

class Resource{
private int num = 0;
private boolean flag;
public void setResource(){
synchronized(this){
System.out.println("set...wait");
if(flag)
try {
Thread.sleep(100);
wait();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("set....notify");
num++;
flag = true;
System.out.println("in...."+num);
notify();
}
}
public void outResource(){
synchronized(this){
System.out.println("out...wait");
if (!flag)
try {
Thread.sleep(100);
wait();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("out...notify");
System.out.println("out...."+num);
flag = false;
notify();
}
}
}
class InDemo implements Runnable{
private Resource r;
public InDemo(Resource r) {
this.r = r;
}
@Override
public void run() {
while(true){
r.setResource();
}
}
}
class OutDemo implements Runnable{
private Resource r;
public OutDemo(Resource r) {
this.r = r;
}
@Override
public void run() {
while(true)
r.outResource();
}
}
public class ThreadDemo{
public static void main(String[] args) {
Resource r = new Resource();
InDemo in = new InDemo(r);
OutDemo out = new OutDemo(r);
new Thread(in).start();
new Thread(out).start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: