- 通過子類繼承開啟多線程
public class Demo {
public static void main(String[] args) throws IOException {
MyThread myThread = new MyThread();
myThread.start();
for(int i = 0;i<1000;i++){
System.out.print("b");
}
}
}
class MyThread extends Thread {
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.print("a");
}
}
}
- 通過實(shí)現(xiàn)Runnable接口開啟多線程
public class Demo {
public static void main(String[] args) throws IOException {
MyThread myThread = new MyThread();
Thread t = new Thread(myThread);
t.start();
for (int i = 0; i < 1000; i++) {
System.out.print("b");
}
}
}
class MyThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.print("a");
}
}
}
- 通過匿名內(nèi)部類實(shí)現(xiàn)多線程
// 方法1
public static void main(String[] args) throws IOException {
new Thread(){
@Override
public void run() {
for(int i = 0;i<1000;i++){
System.out.print("a");
}
}
}.start();
for(int i = 0;i<1000;i++){
System.out.print("b");
}
}
// 方法2
public static void main(String[] args) throws IOException {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.print("a");
}
}
}) {
}.start();
for (int i = 0; i < 1000; i++) {
System.out.print("b");
}
}
- 設(shè)置和獲取線程名稱(setName&getName)
public class Demo {
public static void main(String[] args) throws IOException {
new Thread("subThread A") { // 通過構(gòu)造方法修改名稱
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(this.getName());
}
}
}.start();
new Thread() {
@Override
public void run() {
this.setName("subThread B"); // 通過setName方法 修改線程名稱
for (int i = 0; i < 1000; i++) {
System.out.println(this.getName());
}
}
}.start();
}
}
- 獲取當(dāng)前線程對(duì)象(Thread.currentThread)
public class Demo {
public static void main(String[] args) throws IOException {
new Thread("subThread A") { // 通過構(gòu)造方法修改名稱
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(this.getName());
}
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.print(Thread.currentThread().getName()); // 通過Runnable方法實(shí)現(xiàn)的多線程,無法通過this獲取Thread類對(duì)象,只能通過Thread.currentThread獲取當(dāng)前線程
}
}
}) {
}.start();
// 通過Thread.currentThread方法獲取和設(shè)置主線程屬性
Thread.currentThread().setName("我是主線程");
System.out.println(Thread.currentThread().getName());
}
}
- 線程休眠(sleep)
public class Demo {
public static void main(String[] args) throws IOException {
new Thread() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(new MyDatetime(System.currentTimeMillis()).getCn());
try { // 每次線程執(zhí)行一次則休眠一秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
- 守護(hù)線程(setDaemon)
public class Demo {
public static void main(String[] args) throws IOException {
Thread t1 = new Thread() { // 這里是守護(hù)線程
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.print("a"); // 執(zhí)行1000次打印
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.print("b"); // 執(zhí)行5次打印
}
}
};
t1.setDaemon(true);
t1.start();
t2.start();
// 結(jié)論:當(dāng)正常線程結(jié)束后,守護(hù)線程跟隨停止
}
}
- 加入線程(join)
public class Demo {
public static void main(String[] args) throws IOException {
final Thread t1 = new Thread() { // 匿名內(nèi)部類在使用其方法的時(shí)候需要使用final修飾
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.print("a");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (i == 2) {
try {
t1.join();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("b");
}
}
};
t1.start();
t2.start();
// 執(zhí)行結(jié)果:abbaaaaaaaaabbbbbbb
}
}
public class Demo {
public static void main(String[] args) throws IOException {
final Thread t1 = new Thread() { // 匿名內(nèi)部類在使用其方法的時(shí)候需要使用final修飾
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.print("a");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (i == 2) {
try {
t1.join(10); // 當(dāng)b線程執(zhí)行完成后,交還給a執(zhí)行10毫秒,再次交替執(zhí)行
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("b");
}
}
};
t1.start();
t2.start();
// 執(zhí)行結(jié)果:abbaabbbbbbbbaaaaaaa
}
}
- 同步代碼塊(synchronized)
public class Demo {
public static void main(String[] args) throws IOException {
final Person person = new Person();
new Thread() {
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
person.printNum();
System.out.println();
}
}
}.start();
new Thread() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
person.printLetter();
System.out.println();
}
}
}.start();
}
}
class Person {
public void printNum() {
// 強(qiáng)制程序執(zhí)行時(shí),執(zhí)行該代碼塊完全執(zhí)行后,再跳轉(zhuǎn)其他線程。同步代碼塊
synchronized (this) {
System.out.print("1");
System.out.print("2");
System.out.print("3");
System.out.print("4");
System.out.print("5");
}
}
public void printLetter() {
synchronized (this) {
System.out.print("a");
System.out.print("b");
System.out.print("c");
System.out.print("d");
System.out.print("e");
}
}
}
- 同步方法
public class Demo {
public static void main(String[] args) throws IOException {
final Person person = new Person();
new Thread() {
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
person.printNum();
System.out.println();
}
}
}.start();
new Thread() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
person.printLetter();
System.out.println();
}
}
}.start();
}
}
class Person {
// 同步方法
public synchronized void printNum() {
System.out.print("1");
System.out.print("2");
System.out.print("3");
System.out.print("4");
System.out.print("5");
}
public void printLetter() {
synchronized (this) {
System.out.print("a");
System.out.print("b");
System.out.print("c");
System.out.print("d");
System.out.print("e");
}
}
// 靜態(tài)同步方法
public static synchronized void printNum2() {
System.out.print("1");
System.out.print("2");
System.out.print("3");
System.out.print("4");
System.out.print("5");
}
public static void printLetter2() {
synchronized (Person.class) {
System.out.print("a");
System.out.print("b");
System.out.print("c");
System.out.print("d");
System.out.print("e");
}
}
}
- 多線程安全
public class Demo {
public static void main(String[] args) throws IOException {
// 同時(shí)打開4個(gè)售票窗口進(jìn)行售票
new Ticket().start();
new Ticket().start();
new Ticket().start();
new Ticket().start();
}
}
// 售票窗口
class Ticket extends Thread {
private static int ticket = 100;
@Override
public void run() {
while (true) {
synchronized (Ticket.class) { // 必須使用靜態(tài)
if (ticket <= 0) {
// 防止出現(xiàn)0號(hào)或負(fù)號(hào)票
break;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第" + ticket-- + "張票");
}
}
}
}
- 多線程安全(死鎖)
public class Demo {
private static String s1 = "《筷子左》";
private static String s2 = "《筷子右》";
public static void main(String[] args) throws IOException {
// 使用者1
new Thread("使用者1") {
@Override
public void run() {
while(true){
synchronized (s1) {
System.out.println(this.getName() + ":拿到" + s1 + "等待" + s2);
synchronized (s2) {
System.out.println(this.getName() + ":拿到" + s2 + "開吃");
}
}
}
}
}.start();
// 使用者2
new Thread("使用者2") {
@Override
public void run() {
while(true){
synchronized (s2) {
System.out.println(this.getName() + ":拿到" + s2 + "等待" + s1);
synchronized (s1) {
System.out.println(this.getName() + ":拿到" + s1 + "開吃");
}
}
}
}
}.start();
}
}