1、特點
不用繼承Thread類、能實現資源共享
2、基本例子
public class Run implements Runnable {
private int count = 1;
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + " 運行 " + count++);//獲取當前執行這段代碼的線程的名字,且變量自增
}
}
public static void start() {
Run r = new Run();
new Thread(r, "線程A").start();
new Thread(r, "線程B").start();
new Thread(r, "線程C").start();
}
}
3、多線程中使用synchronized(鎖)
上面例子中的代碼,如果不使用synchronized線程是不安全,因爲多個線程有可能在同一時間操作變量,就會導致執行兩次結果只自增1。所以可以用synchronized來實現線程安全,讓變量在同一時間只讓一個線程操作。
public class Run implements Runnable {
public static void start() {
Run aa = new Run();
new Thread(aa, "線程A").start();
new Thread(aa, "線程B").start();
new Thread(aa, "線程C").start();
}
private int count = 1;
@Override
public void run() {
synchronized (this) {
for (int i = 0; i < 100000; i++) {
System.out.println(Thread.currentThread().getName() + " 運行 " + count++);//獲取當前執行這段代碼的線程的名字,變量自增
}
}
}
}
4、多線程中使用原子類型AtomicInteger
另一種保證線程安全的方法,JDK1.5之後引入一批原子處理類:AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference。主要用於在高併發環境下的高效程序處理,來幫助我們簡化同步處理.
public class Run implements Runnable {
public static void start() {
Run aa = new Run();
new Thread(aa, "線程A").start();
new Thread(aa, "線程B").start();
new Thread(aa, "線程C").start();
}
private AtomicInteger count = new AtomicInteger(1);
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + " 運行 " + count.getAndIncrement());
}
}
}
5、用匿名內部類的方式實現Runnble接口
public class Run {
public static void test() {
Run r = new Run();
new Thread(r.runnable, "線程A").start();
new Thread(r.runnable, "線程B").start();
}
private int count = 1;
public Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + " 運行 " + count++);//獲取當前執行這段代碼的線程的名字,變量自增
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
}
6、用 匿名內部類+lambda表達式 的方式實現Runnble接口
public class Run {
public static void test() {
Run r = new Run();
new Thread(r.runnable, "線程A").start();
new Thread(r.runnable, "線程B").start();
}
private int count = 1;
public Runnable runnable = () -> {
for (int i = 0; i < 10; i++) {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + " 運行 " + count++);//獲取當前執行這段代碼的線程的名字,變量自增
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}